使用C#驱动程序从MongoDB Collection上的文本查询中检索相关性排序结果

我正在尝试文本查询集合并以文本匹配顺序检索结果。 文档很好地解释了如何在shell中执行此操作:

db.articles.find( { status: "A", $text: { $search: "coffee cake" } }, { score: { $meta: "textScore" } } ).sort( { date: 1, score: { $meta: "textScore" } } ) 

但它需要将查找中的附加score字段投影到排序中。

在C#中,我有一个如下所示的函数:

 public IEnumerable TextSearch(MongoCollection coll, string text) { var cursor = coll.Find(Query.Text(text)) .SetSortOrder(SortBy.MetaTextScore(???)); foreach(var t in cursor) { // strip projected score from value yield return t; } } 

但我错过了如何将“textScore”值投影到我的结果中,以便我可以在SetSortOrder 指定 MetaTextScore 的列 。

我能够通过反复试验来解决这个问题。 诀窍是你的数据对象需要有一个字段,它将保留MetaTextScore值。 所以给出了界面:

 interface ITextSearchSortable { double? TextMatchScore { get; set; } } 

最终函数如下所示:

 public IEnumerable TextSearch(MongoCollection coll, string text) where T:ITextSearchSortable { var cursor = coll.Find(Query.Text(text)) .SetFields(Fields.MetaTextScore(t => t.TextMatchScore)) .SetSortOrder(SortByMetaTextScore(t => t.TextMatchScore)); foreach(var t in cursor) { // prevent saving the value back into the database t.TextMatchScore = null; yield return t; } } 

值得注意的是TextMatchScore不能有[BsonIgnore]装饰,否则会有exception。 但是,它可以有[BsonIgnoreIfNull]装饰。 因此,通过在产生数据对象之前擦除数据对象的值,可以将数据对象保存回集合中而不会产生垃圾值。