忍受我,这不是我的问题。只是想让别人理解。
作者注意:
possible duplicate问题解决方案允许$ elemMatch进行约束,因为> 所有元素都是数组。这有点不同。
因此,在接受的答案中,提出了要点。这种行为很好 记录,不应 “将'apples'`与'oranges'进行比较”。这些领域是 不同的类型,虽然有一个解决方法,这是真正的最佳解决方案 世界不要这样做。
快乐阅读:)
我有一系列我想要搜索的文档,该集合包含以下内容:
{ "_id" : ObjectId("52faa8a695fa10cc7d2b7908"), "x" : 1 }
{ "_id" : ObjectId("52faa8ab95fa10cc7d2b7909"), "x" : 5 }
{ "_id" : ObjectId("52faa8ad95fa10cc7d2b790a"), "x" : 15 }
{ "_id" : ObjectId("52faa8b095fa10cc7d2b790b"), "x" : 25 }
{ "_id" : ObjectId("52faa8b795fa10cc7d2b790c"), "x" : [ 5, 25 ] }
所以我想找到 x 落在10
和20
之间的结果。所以这是对我来说合乎逻辑的查询:
db.collection.find({ x: {$gt: 10, $lt: 20} })
但问题是这会在结果中返回两个文件:
{ "_id" : ObjectId("52faa8ad95fa10cc7d2b790a"), "x" : 15 }
{ "_id" : ObjectId("52faa8b795fa10cc7d2b790c"), "x" : [ 5, 25 ] }
我不希望看到第二个结果,因为10
和20
之间没有任何值。
有人可以解释为什么我没有得到我期望的结果吗?我认为 {“x”:15} 应该是唯一返回的文档。
此外,我怎样才能得到我期望的东西?
答案 0 :(得分:2)
mongo文档here中预期并解释了此行为。
查询包含数组的字段
如果某个字段包含数组且您的查询有多个条件 运算符,如果是单个数组,整个字段将匹配 元素满足条件或 数组元素的组合 符合条件。
当数组元素的组合独立地匹配所有条件时,Mongo似乎愿意通过回馈结果来“玩笑”。
在我们的示例中,5匹配$ lt:20条件,25匹配$ gt:10条件。所以,这是一场比赛。
以下两项都将返回[5,25]结果:
db.collection.find({ x: {$gt: 10, $lt: 20} })
db.collection.find({ $and : [{x: {$gt: 10}},{x:{ $lt: 20}} ] })
如果这是用户预期的行为,意见可能会有所不同。但它肯定是有记录的,应该是预期的。
编辑,针对Neil对原始答案的虐待狂和高度教育性的编辑,寻求解决方案:
使用$elemMatch可以对数组进行“更严格”的元素比较。
db.collection.find({ x: { $elemMatch:{ $gt:10, $lt:20 } } })
注意:这将匹配x:[11,12] 和 x:[11,25]
我相信当需要这样的查询时,需要对两个查询进行组合,并将结果合并。下面是一个查询,它返回x为不是数组的文档的正确结果:
db.collection.find( { $where : "!Array.isArray(this.x)", x: {$gt: 10, $lt: 20} } )
但在这种情况下,最佳方法是将x的类型更改为始终为数组,即使它只包含一个元素。然后,只需要$ elemMatch查询就可以获得正确的结果,并且具有预期的行为。
答案 1 :(得分:2)
您可以先检查子文档是否不和数组,并提供所需值的过滤器:
db.collection.find(
{
$and :
[
{ $where : "!Array.isArray(this.x)" },
{ x: { $gt: 10, $lt: 20 } }
]
}
)
返回:
{ "_id" : ObjectId("52fb4ec1cfe34ac4b9bab163"), "x" : 15 }