使用MongoDBObject查询生成器与Salat



我试图提供一个API来搜索MongoDB集合上的各种标准,包括全文搜索。因为这是一个Scala项目(在Play FWIW中),我使用的是Salat,一个围绕Casbah的抽象。

下面的代码可以正常工作:

MySalatDao
.find(MongoDBObject("$text" -> MongoDBObject("$search" -> "Vidya")), MongoDBObject("score" -> MongoDBObject("$meta" -> "textScore")))
.sort(orderBy = MongoDBObject("score" -> MongoDBObject("$meta" -> "textScore")))

然而,我最终需要在多个条件下进行搜索,并根据全文搜索分数对结果进行排序,因此我探索了Casbah的MongoDBObject查询构建器功能(在底部)。

所以我试着像这样复制上面的内容:

val builder = MongoDBObject.newBuilder
builder += "$text" -> MongoDBObject("$search" -> "Vidya")
builder += "score" -> MongoDBObject("$meta" -> "textScore")
MySalatDao
.find(a.result())
.sort(orderBy = MongoDBObject("score" -> MongoDBObject("$meta" -> "textScore")))

给出如下异常:

com.mongodb.MongoException: Can't canonicalize query: BadValue must have $meta projection for all $meta sort keys
  at com.mongodb.QueryResultIterator.throwOnQueryFailure(QueryResultIterator.java:214)
  at com.mongodb.QueryResultIterator.init(QueryResultIterator.java:198)
  at com.mongodb.QueryResultIterator.initFromQueryResponse(QueryResultIterator.java:176)
  at com.mongodb.QueryResultIterator.<init>(QueryResultIterator.java:64)
  at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:86)
  at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:66)
.
.

我以前见过这个错误——当我没有在查询中包含score组件时。但是,一旦我这样做了,它就工作了(如第一个代码片段所示),并且我认为带有查询构建器的版本是等效的。

对于这个问题,对builder.result().toString()的调用产生如下:

{ "$text" : { "$search" : "Vidya"} , "score" : { "$meta" : "textScore"}}

获得查询生成器为我工作的任何帮助将不胜感激。

在您的工作查询中,您正在传递一个DBObject用于"查询谓词"和第二个DBObject用于"字段"或"投影" - find需要第二个可选参数,指示返回哪些字段,并且在$文本搜索的情况下,有一个特殊的投影字段$meta,它允许您获得匹配文档的分数,以便您可以对其进行排序。

在您的构建器尝试中,您正在将投影DBObject添加到查询条件中,并且这会给您提供与您之前在省略score组件作为查找的第二个参数时看到的相同的错误。

添加MongoDBObject("score" -> MongoDBObject("$meta" -> "textScore"))作为第二个参数来查找,就像你以前做的那样,并使用builder来组合多个查询条件。

在简单的JSON术语中,你像这样调用find:

  db.coll.find( { "$text" : { "$search" : "Vidya"} , "score" : { "$meta" : "textScore"}} )

当你真正想这样调用它时:

  db.coll.find( { "$text" : { "$search" : "Vidya"} } , { "score" : { "$meta" : "textScore"}} )

相关内容

  • 没有找到相关文章

最新更新