2

我有一个包含数组的文档:

{
    _id: ObjectId("515e10784903724d72000003"),
    association_chain: [
        {
            name: "Product",
            id: ObjectId("4e1e2cdd9a86652647000003")
        }
    ],
    //...
}

我正在尝试在集合中搜索数组中name第一项与给定值匹配的文档。association_chain

如何使用 Mongoid 做到这一点?或者,如果您只知道如何使用 MongoDB 来完成,如果您发布一个示例,那么我可能会弄清楚如何使用 Mongoid 来完成。

4

3 回答 3

5

使用位置运算符。.0您可以使用(以及使用.1等)查询数组的第一个元素。

> db.items.insert({association_chain: [{name: 'foo'}, {name: 'bar'}]})
> db.items.find({"association_chain.0.name": "foo"})
{ "_id" : ObjectId("516348865862b60b7b85d962"), "association_chain" : [ { "name" : "foo" }, { "name" : "bar" } ] }

您可以看到位置运算符有效,因为在foo第二个元素中搜索不会返回命中...

> db.items.find({"association_chain.1.name": "foo"})
>

...但搜索bar确实如此。

> db.items.find({"association_chain.1.name": "bar"})
{ "_id" : ObjectId("516348865862b60b7b85d962"), "association_chain" : [ { "name" : "foo" }, { "name" : "bar" } ] }

您甚至可以在不索引所有关联链文档的所有名称的情况下索引此特定字段:

> db.items.ensureIndex({"association_chain.0.name": 1})
> db.items.find({"association_chain.0.name": "foo"}).explain()
{
        "cursor" : "BtreeCursor association_chain.0.name_1",
        "nscanned" : 1,
        ...

}
> db.items.find({"association_chain.1.name": "foo"}).explain()
{
        "cursor" : "BasicCursor",
        "nscanned" : 3,
        ...
}
于 2013-04-08T22:46:13.343 回答
3

有两种方法可以做到这一点:

1)如果您已经知道您只对出现在“association_chain”中的第一个产品名称感兴趣,那么这样会更好:

db.items.find("association_chain.0.name":"something")

请注意,这不会返回所有提及所需产品的项目,而只会返回那些在“association_chain”数组的第一个位置提及的项目。

如果你想这样做,那么你需要一个索引:

db.items.ensureIndex({"association_chain.0.name":1},{background:1})

2)如果您正在寻找特定产品,但不确定它出现在 Association_chain 的哪个位置,请执行以下操作:

使用 MongoDB shell,您可以使用 '.' 访问嵌套结构内的任何哈希键。点运算符!请注意,这与该键在记录中嵌套的深度无关(不是很酷吗?)

您可以像这样对嵌入的哈希数组进行查找:

db.items.find("association_chain.name":"something")

这将返回集合中包含关联数组中任何位置提到的所需产品的所有记录。

如果你想这样做,你应该确保你有一个索引:

db.items.ensureIndex({"association_chain.name":1},{background: 1})

请参阅此页面上的“点表示法”:http: //docs.mongodb.org/manual/core/document/

于 2013-04-08T22:59:47.453 回答
1

您可以使用聚合框架来做到这一点。在 mongo shell 中运行一个展开文档的查询,以便每个数组元素都有一个文档(在其他字段中有重复的数据),然后按 id 和要包含的任何其他字段分组,加上带有运算符 $first 的数组. 然后只需包含 $match 运算符即可按名称或 mongoid 进行过滤。

这是与第一个产品名称匹配的查询:

db.foo.aggregate([
{ $unwind:"$association_chain"     
},
{
  $group : {
            "_id" : {
                "_id" : "$_id",
                "other" : "$other"
            },
            "association_chain" : {
                $first : "$association_chain"
            }
        }
},
{  $match:{ "association_chain.name":"Product"}
}

])

以下是通过 mongoid 查询第一个产品的方法:

db.foo.aggregate([
{ $unwind:"$association_chain"     
},
{
   $group : {
            "_id" : {
                "_id" : "$_id",
                "other" : "$other"
            },
            "association_chain" : {
                $first : "$association_chain"
            }
        }
},
{  $match:{ "association_chain.id":ObjectId("4e1e2cdd9a86652647000007")}
}

])
于 2013-04-08T21:46:14.420 回答