2015-04-19 45 views
0

「文本」命令,該查詢工作正常,我:無法執行我試圖用MongoDB的3 進行全文搜索從C#

var q = new QueryDocument(BsonSerializer.Deserialize<BsonDocument>(string.Format("{{ $text: {{ $search: {0} }} }}", JsonConvert.ToString(query.Query))); 
return await context.Books.Find(q).ToListAsync(); 

但現在我想通過相關性排序結果使用textScore字段。 我試圖用這樣的代碼:

public static async Task<IEnumerable<T>> Search<T>(this IMongoDatabase database, string search)  where T : class, new() 
     { 
      var textSearchCommand = new CommandDocument 
      { 
       { "text", typeof(T).Name }, 
       { "search", search } 
      }; 
      var commandResult = await database.RunCommandAsync<TextSearchQueryResult<T>>( textSearchCommand); 

      return commandResult.Ok ? commandResult.Results.OrderBy(t => t.Score).Select(t => t. Record) : null; 
     } 

class TextSearchQueryResult<T> : CommandResult 
{ 
    public TextSearchQueryResult(BsonDocument response) 
     : base(response) 
    { 
    } 

    public IEnumerable<TextSearchResult<T>> Results 
    { 
     get 
     { 
      var results = Response["results"].AsBsonArray.Select(row => row.AsBsonDocument); 
      var resultObjects = results.Select(item => item.AsBsonDocument); 

      return resultObjects.Select(row => BsonSerializer.Deserialize<TextSearchResult<T>>(row)); 
     } 
    } 
} 

public class TextSearchResult<T> 
{ 
    public T Record { get; set; } 
    public double Score { get; set; } 
} 

啓動這個命令我得到這樣一個錯誤:

Command text failed: no such command: text 

另一種方法,我發現:

return await context.Books 
        .Find(Builders<Book>.Filter.Text(query.Query)) 
        //.Project(Builders<Book>.Projection.Include(new StringFieldDefinition<Book>("textScore"))) 
        .Sort(Builders<Book>.Sort.MetaTextScore("textScore")) 
        .ToListAsync(); 

但在這種情況我得到這樣的錯誤:

Can't canonicalize query: BadValue must have $meta projection for all $meta sort keys (code: 17287) 

回答

0

我發現了一種可能的方法,使用aggregation

var pipeline = new List<BsonDocument> 
{ 
    BsonSerializer.Deserialize<BsonDocument>("{ $match: { $text: { $search: " + JsonConvert.ToString(query.Query) + " } } }"), 
    BsonSerializer.Deserialize<BsonDocument>("{ $sort: { score: { $meta: \"textScore\" } } }") 
}; 

var result = await context.Books.AggregateAsync(new BsonDocumentStagePipelineDefinition<Book, Book>(pipeline)); 
return await result.ToListAsync(); 

,我可以看到的結果不同於我以前的做法。而且似乎接近相關結果。