我一直在努力使用 Scala mongo 驱动程序中的 MongoDB 过滤器。我正在尝试获取集合中的所有文档,其中文档中的特定字符串位于字符串列表中。我在 Scala 中创建一个字符串列表,然后使用 IN 运算符构建查询:
val find3 = in(EventItem, ListDelayedItems.toList)
根据文档,in有两个重载方法:
public static <TItem> Bson in(String fieldName,
TItem... values)
public static <TItem> Bson in(String fieldName,
Iterable<TItem> values)
问题是,我不知道如何构造 Iterable 值。如果我将值作为值列表传递(请参阅第一个重载方法),
in(EventItem, "ABCDE", "DEF", "ESO4SAP")
它有效。这是我在打印 in 运算符过滤器时看到的内容
Operator Filter{fieldName='billing_event.action.resources.item', operator='$in', value=[ABCDE, DEF, ESO4SAP]}
但是当我尝试在第二个参数中传递一个列表以使用第二个重载方法时,它就不起作用了。我试图用来过滤的列表是动态的。我已经尝试过 scala Lists、ListBuffers、java.util.Lists 但每次我使用这样的变量时:
in(EventItem, ListValidItems)
它停止工作。我将 ListValidItems 定义为我知道的每个集合,但是当我看到日志时,我看到了这个:
Operator Filter{fieldName='billing_event.action.resources.item', operator='$in', value=[List(ABCDE, EFGH, ESO4SAP)]}
所以它从 value=[ABCDE, DEF, ESO4SAP] 到 value=[List(ABCDE, EFGH, ESO4SAP)] 并且过滤器不起作用。
正如我提到的,我尝试了很多不同的列表,尝试了 list.toIterator 但似乎没有任何方法可以将列表数据结构转换为值列表 TItem... 或 Iterable
这是 mongoDB 驱动程序的导入列表
import org.mongodb.scala.connection.ClusterSettings
import com.mongodb.BasicDBObject
import com.mongodb.client.model.{FindOneAndReplaceOptions, FindOneAndUpdateOptions}
import org.mongodb.scala.ServerAddress
import org.mongodb.scala._
import org.mongodb.scala.bson.{BsonDocument, conversions}
import org.mongodb.scala.model.Filters._
import org.mongodb.scala.model.Updates._
有什么想法吗?
谢谢!!
最佳答案
根据Filters#in
的签名, values
参数是可变参数。这就是它支持传递任意数量参数的语法的方式,如下所示:
scala> in(EventItem, "ABCDE", "DEF", "ESO4SAP")
res1: org.mongodb.scala.bson.conversions.Bson = Operator Filter{fieldName='EventItem', operator='$in',
value=[ABCDE, DEF, ESO4SAP]}
但是,在您的情况下,您有一个集合,例如 Scala List
,您希望用变量值构建它,然后传递给 in
。直接这样做,in
最终将 values
解释为单个值,即包含元素的 List
本身。
scala> val ListValidItems = List("ABCDE", "DEF", "ESO4SAP")
ListValidItems: List[String] = List(ABCDE, DEF, ESO4SAP)
scala> in(EventItem, ListValidItems)
res2: org.mongodb.scala.bson.conversions.Bson = Operator Filter{fieldName='EventItem', operator='$in',
value=[List(ABCDE, DEF, ESO4SAP)]}
它需要一些额外的语法 (ListValidItems:_*
) 来“展开”集合以将其各个元素作为可变参数传递:
scala> in(EventItem, ListValidItems:_*)
res4: org.mongodb.scala.bson.conversions.Bson = Operator Filter{fieldName='EventItem', operator='$in',
value=[ABCDE, DEF, ESO4SAP]}
关于 Types 的 Scala 文档讨论了这一点,特别是关于 Ascription 的部分.
早些时候,您似乎试图从 Scala 代码中调用 Java API,这由您的问题陈述中存在 Java 方法签名表明:
public static <TItem> Bson in(String fieldName,
TItem... values)
public static <TItem> Bson in(String fieldName,
Iterable<TItem> values)
如果那是您想要做的,那么您可以准备 ListValidItems
作为您选择的 Scala 集合,然后在传递给 in
之前转换为等效的 Java 集合>。 Java 集合将实现 Java Iterable
接口(interface)。
最简单的方法是使用 JavaConverters
Scala 中包含的对象。如果导入它,那么它将向集合类添加扩展方法以支持转换。这是 REPL 中的演示。
scala> // Import converters.
scala> import collection.JavaConverters._
import collection.JavaConverters._
scala> // Create Scala List.
scala> val ListValidItems = List("ABCDE", "DEF", "ESO4SAP")
ListValidItems: List[String] = List(ABCDE, DEF, ESO4SAP)
scala> // Convert to Java List.
scala> val ListValidItemsConverted = ListValidItems.asJava
ListValidItemsConverted: java.util.List[String] = [ABCDE, DEF, ESO4SAP]
scala> // Prove that it is a Java Iterable.
scala> ListValidItemsConverted.asInstanceOf[java.lang.Iterable[java.lang.String]]
res8: Iterable[String] = [ABCDE, DEF, ESO4SAP]
有关详细信息,请参阅 Conversions Between Java and Scala Collections在Scala Guides and Overviews .
关于mongodb - scala mongodb IN过滤器使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45243514/