使用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(SortBy MetaTextScore(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]
装饰。 因此,通过在产生数据对象之前擦除数据对象的值,可以将数据对象保存回集合中而不会产生垃圾值。