【问题标题】:MongoDB: Match multiple array elementsMongoDB:匹配多个数组元素
【发布时间】:2013-03-12 15:09:58
【问题描述】:

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

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 and Value="a") 和 (Type=2 and 值="b")

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

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

更新:

$all 查询效果更好,因为 $and 有问题(请参阅我在 JohnnyHK 答案中的评论)。感谢您的帮助。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    在这种情况下,如果您希望文档包含一组特定的数组元素,您可以使用 $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" }
            }}
        ]
    })
    

    【讨论】:

    • 是否有替代 $all 运算符 (jira.mongodb.org/browse/SERVER-1748) 的方法?此运算符存在一个未解决的错误会导致性能下降,并且看起来在未来 2 年内不会修复
    • @Kamarey 你也可以用$and 来做,但我不知道它是否会更快。查看更新的答案。
    • 这是不对的。你想要$all $elemMatch。有关示例,请参见第二个索引:chemeo.com/doc/technology
    • @AsyaKamsky 这两个在我测试时都有效。 $all 元素的行为就像您为每个元素指定了 $elemMatch
    • 那是因为这是一个糟糕的测试数据集,无法找到那个错误。
    猜你喜欢
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2013-10-01
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    相关资源
    最近更新 更多