简体   繁体   English

find_one()返回一个给出字段组合的文档

[英]find_one() return one document give a combination of fields

I am trying to return a document from my mongodb (using pymongo). 我正在尝试从mongodb返回文档(使用pymongo)。 I want the query to return a document given an id and a tag. 我希望查询返回给定ID和标签的文档。

ids = ['123', '456', '234', '534']

rows = []
for i in ids:
    for b in ["Tag1", "Tag2", "Tag3"]:
        temp = pb_db.db.collection.find_one({"ID": i, "Tag": b}, {'ID': 1, 'Tag': 1, 'Name': 1, '_created_at': 1})
        if temp is not None:
            rows.append(temp)

A document with an ID of '123' may have one record with 'Tag1' and a separate document with 'Tag3'. ID为'123'的文档可能具有一个带有'Tag1'的记录,而另一个文档具有'Tag3'。 Any combination of 'ID' and 'Tag' is possible. “ ID”和“ Tag”的任何组合都是可能的。

The goal is to return one instance of each id, tag combination (hence using find_one()) 目标是返回每个ID,标记组合的一个实例(因此使用find_one())

At the moment my code above is very inefficient as it queries the db for every id three times (my list of ids is much larger than this example). 目前,我上面的代码效率很低,因为它为每个id查询数据库3次(我的id列表比此示例大得多)。 Is it possible to use the find_one() query to return a document for a given id with each tag only once? 是否可以使用find_one()查询为每个标签返回给定ID的文档一次? Thanks, 谢谢,

example mongo structure: 示例mongo结构:

{
    "_id" : "random_mongo_id",
    "Tag" : "Tag1",
    "_created_at" : ISODate("2016-06-25T00:00:00.000Z"),
    "ID" : [ 
        "123"
    ],
},
{
    "_id" : "random_mongo_id",
    "Tag" : "Tag2",
    "_created_at" : ISODate("2016-07-25T00:00:00.000Z"),
    "ID" : [ 
        "123"
    ],
},
{
    "_id" : "random_mongo_id",
    "Tag" : "Tag1",
    "_created_at" : ISODate("2016-07-25T00:00:00.000Z"),
    "ID" : [ 
        "534"
    ],
}

so in this example i would expect to see: 因此,在此示例中,我希望看到:

ID: 123, Tag: Tag1
ID: 123, Tag: Tag2
ID: 534, Tag: Tag1

You need to use $in and the $elemMatch query operator. 您需要使用$in$elemMatch查询运算符。

ids = ['123', '456', '234', '534']
tags = ["Tag1", "Tag2", "Tag3"]

db.collection.find_one({
    "Tag": { "$in": tags}, 
    "ID": { "$elemMatch": { "$in": ids}}
})

You could do it in a single pass by using the $in operator to compare the items in the "ID" array in the database with the items in the "ids" array variable, and similarly for the tags. 您可以使用$ in运算符将数据库中“ ID”数组中的项目与“ ids”数组变量中的项目(以及类似地用于标记)进行比较,从而一次性完成。

Use the $in Operator to Match Values in an Array 使用$ in运算符匹配数组中的值

The collection inventory contains documents that include the field tags, as in the following: 收集清单包含包含字段标签的文档,如下所示:

{ _id: 1, item: "abc", qty: 10, tags: [ "school", "clothing" ], sale: false }

Then, the following update() operation will set the sale field value to true where the tags field holds an array with at least one element matching either "appliances" or "school". 然后,下面的update()操作会将sale字段的值设置为true,其中tags字段包含一个数组,其中至少一个元素与“ appliances”或“ school”匹配。

db.inventory.update(
  { tags: { $in: ["appliances", "school"] } },
  { $set: { sale:true } }
)

In user3939059's case, the query would be something like this: 在user3939059的情况下,查询将如下所示:

ids = ['123', '456', '234', '534']
tags = ['Tag1', 'Tag2', 'Tag3']

pb_db.db.collection.find({"ID": {$in: ids}, "Tag": {$in: tags}}, {'ID': 1, 'Tag': 1, 'Name': 1, '_created_at': 1})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM