MongoDB:匹配多个数组元素

Kam*_*rey 5 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});
Run Code Online (Sandbox Code Playgroud)

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

  1. 匹配位置
  2. 包含具有(Type = 1和Value ="a")和(Type = 2和Value ="b")的属性

这是我的查询(它不起作用,但看起来接近正确的):

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

更新:

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

Joh*_*yHK 11

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

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

要在没有$all操作员的情况下完成,您可以使用:

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