簡體   English   中英

Pymongo在子文檔中發現價值

[英]Pymongo find value in subdocuments

我正在使用MongoDB 4和Python3。我有3個集合。 第一個集合在其他集合上有2個引用字段。

范例:

User {
   _id  : ObjectId("5b866e8e06a77b30ce272ba6"),
   name : "John",
   pet  : ObjectId("5b9248cc06a77b09a496bad0"),
   car  : ObjectId("5b214c044ds32f6bad7d2"),
}

Pet {
   _id  : ObjectId("5b9248cc06a77b09a496bad0"),
   name : "Mickey",
}

Car {
   _id   : ObjectId("5b214c044ds32f6bad7d2"),
   model : "Tesla"
}

因此,一位用戶有一輛汽車和一只寵物。 我需要查詢User集合並查找是否有一個用戶,其Pet的名稱為“ Mickey”,而Car的模型為“ Tesla”。

我嘗試了這個:

db.user.aggregate([{
    $project : {"pet.name" : "Mickey", "car.model" : "Tesla"  } 
}])

但是,當我只有一個文檔使用此數據時,它返回了很多數據。 我做錯了什么?

您需要在此處使用$lookup聚合。

像這樣

db.users.aggregate([
  { "$lookup": {
    "from": Pet.collection.name,
    "let": { "pet": "$pet" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": ["$_id", "$$pet"] }, "name" : "Mickey"}}
    ],
    "as": "pet"
  }},
  { "$lookup": {
    "from": Car.collection.name,
    "let": { "car": "$car" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": ["$_id", "$$car"] }, "model" : "Tesla"}}
    ],
    "as": "car"
  }},
  { "$match": { "pet": { "$ne": [] }, "car": { "$ne": [] } }},
  { "$project": { "name": 1 }}
])

@AnthonyWinzlet發布的答案有一個缺點,那就是它需要遍歷users集合中的所有文檔並執行$lookup ,這是相對昂貴的。 因此,根據Users集合的大小,執行此操作可能會更快:

  1. users.petusers.car上放置一個索引: db.users.createIndex({pet: 1, car: 1})
  2. cars.modelcars.model索引: db.cars.createIndex({model: 1})
  3. 將索引放在pets.namedb.pets.createIndex({name: 1})

然后,您可以簡單地執行以下操作:

  1. 獲取所有匹配的"Tesla"汽車的列表: db.cars.find({model: "Tesla"})
  2. 獲取所有匹配的"Mickey"寵物的列表: db.pets.find({name: "Mickey"})
  3. 查找您感興趣的用戶: db.users.find({car: { $in: [<ids from cars query>] }, pet: { $in: [<ids from pets query>] }})

這非常容易閱讀和理解,而且所有三個查詢都完全被索引覆蓋,因此可以期望它們盡可能快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM