MongoDB:匹配多个数组元素

时间:2013-03-12 15:09:58

标签: mongodb

我有一个包含下一个数据的集合:

db.MyCollection.insert({ 
        id: 1, 
        Location: [ 1, 1 ],
        Properties: [ { Type: 1, Value: "a" }, { Type: 2, Value: "b" }, { Type: 3, Value: "c" } ]
    });

db.MyCollection.insert({ 
        id: 2, 
        Location: [ 1, 2 ],
        Properties: [ { Type: 1, Value: "a" }, { Type: 2, Value: "a" }, { Type: 3, Value: "c" } ]
    });

db.MyCollection.insert({ 
        id: 3, 
        Location: [ 2, 1 ],
        Properties: [ { Type: 1, Value: "a" }, { Type: 3, Value: "b" }, { Type: 3, Value: "a" } ]
    });

db.MyCollection.insert({ 
        id: 4, 
        Location: [ 2, 2 ],
        Properties: [ { Type: 2, Value: "b" }, { Type: 2, Value: "a" }, { Type: 3, Value: "c" } ]
    });

db.MyCollection.ensureIndex({ Location: "2d"});
db.MyCollection.ensureIndex({ "Properties.Type": 1, "Properties.Value": 1});
db.MyCollection.ensureIndex({ Location: "2d", "Properties.Type": 1, "Properties.Value": 1});

我想要的是找到所有项目(使用上述任何索引):

  1. 匹配位置
  2. 包含属性(Type = 1和Value =“a”)和(Type = 2和 值= “B”)
  3. 这是我的查询(它不起作用,但看起来接近正确的一个):

    db.MyCollection.find(
    { 
        Location: { "$within": { "$center": [ [1, 1], 5 ] } },
        Properties: {
            $elemMatch: {
                $and: [
                    { Type: 1, Value: "a" },
                    { Type: 2, Value: "b" }
                ]
            }
        }
    })
    

    更新

    $ all查询效果更好,因为$和one存在问题(请参阅JohnnyHK答案中的评论)。谢谢你的帮助。

1 个答案:

答案 0 :(得分:10)

在这种情况下,您需要包含一组特定数组元素的文档,您可以使用$all运算符:

db.MyCollection.find(
{ 
    Location: { "$within": { "$center": [ [1, 1], 5 ] } },
    Properties: {
        $all: [
            {$elemMatch: { Type: 1, Value: "a" }},
            {$elemMatch: { Type: 2, Value: "b" }}
        ]
    }
})

如果没有您可以使用的$all运算符,请执行此操作:

db.MyCollection.find(
{ 
    Location: { "$within": { "$center": [ [1, 1], 5 ] } },
    $and: [
        { Properties: {
            $elemMatch: { Type: 1, Value: "a" }
        }},
        { Properties: {
            $elemMatch: { Type: 2, Value: "b" }
        }}
    ]
})