簡體   English   中英

如何查詢MongoDB中有“一對多”關系的兩個collections?

[英]How to query two collections that have a “one-to-many” relationship in MongoDB?

我們有兩個 collections:“房屋”和“事件”。 house 集合中的每個文檔都包含一個“ events ”字段,其中包含一組id引用事件(“一對多”關系)。 數組可以為空。

房子”架構:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const HouseSchema = new Schema({
  name: String,
  district: String,
  locality: String,
  date: {
    type: Date,
    default: Date.now
  },
  events: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Event'
  }]
});

module.exports = mongoose.model('House', HouseSchema);

事件”架構:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const EventSchema = new Schema({
  event: String,
  details: String,
  date: {
    type: Date,
    default: Date.now
  },
  house: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'House'
  }
});

module.exports = mongoose.model('Event', EventSchema);

我需要同時查詢“房屋”和“事件”,並找到那些帶有符合所有標准的“事件”的“房屋”。 我將給出幾個查詢選項。

僅使用來自“房屋”的參數進行查詢。 假設 "houses" 集合中有兩個文檔滿足條件{"locality": "Facebook"} 結果應該是這樣的:

[
  {
    "_id": "601bae8e26ed00591d571dbe",
    "name": "Facebook testing department",
    "district": "Los-Angeles",
    "locality": "Facebook",
    "events": [
      {
        "_id": "601bae8e26ed00591d571dbf",
        "event": "Testing",
        "details": "Testing software for production",
        "date": "2020-07-31T21:00:00.000Z"
      }
    ]
  },
  {
    "_id": "601bae8e26ed00591d571dbc",
    "name": "Facebook office",
    "district": "Los-Angeles",
    "locality": "Facebook",
    "events": [
      {
        "_id": "601bae8e26ed00591d571dbd",
        "event": "Conference",
        "details": "Developers conference about 12345",
        "date": "2020-07-31T21:00:00.000Z"
      }
    ]
  },
];

僅使用“事件”的參數進行查詢。 假設“events”集合中有兩條滿足條件{"event": "Conference"}的記錄。 結果是:

[
  {
    "_id": "601bae8e26ed00591d571dbc",
    "name": "Facebook office",
    "district": "Los-Angeles",
    "locality": "Facebook",
    "events": [
      {
        "_id": "601bae8e26ed00591d571dbd",
        "event": "Conference",
        "details": "Developers conference about 12345",
        "date": "2020-07-31T21:00:00.000Z"
      }
    ]
  },
  {
    "_id": "601bae8e26ed00591d571dba",
    "name": "Oxford",
    "district": "London",
    "locality": "Oxford",
    "events": [
      {
        "_id": "601bae8e26ed00591d571dbb",
        "event": "Conference",
        "details": "About something",
        "date": "2020-07-31T21:00:00.000Z"
      }
    ]
  },
];

查詢“房屋”和“事件”的參數。 如果我們查詢的條件是{"locality": "Facebook", "event": "Conference"} ,那么結果應該是這樣的:

[  
  {
    "_id": "601bae8e26ed00591d571dbc",
    "name": "Facebook office",
    "district": "Los-Angeles",
    "locality": "Facebook",
    "events": [
      {
        "_id": "601bae8e26ed00591d571dbd",
        "event": "Conference",
        "details": "Developers conference about 12345",
        "date": "2020-07-31T21:00:00.000Z"
      }
    ]
  },
];

我遇到過類似的情況,需要使查詢比平時更復雜。 但是在這里,我們需要根據參數對一個或兩個 collections 進行查詢,結果,我們應該得到帶有對應查詢參數的嵌套“事件”的“房屋”。 我不太了解MongoDB 聚合,不勝感激。

  • 聲明你的輸入
let locality = req.body.locality;
let event = req.body.event;
  • 初始化聚合管道(將HousesModel替換為您的 reql model 名稱)
let p = HousesModel.aggregate();
  • 檢查locality條件
if (locality && locality.trim()) p.match({ locality: locality });
  • $lookup與管道,
  • events數組聲明為let
  • 表達式中的匹配事件條件
  • 如果事件搜索可用,則檢查條件然后放置條件
p.lookup({
  from: "events", // replace your actual collection name if this is wrong
  let: { events: "$events" },
  pipeline: [
    {
      $match: {
        $and: [
          { $expr: { $in: ["$_id", "$$events"] } },
          (event && event.trim() ? { event: event } : {})         
        ]
      }
    }
  ],
  as: "events"
});
  • 確保事件不為空
p.match({ events: { $ne: [] } });
  • 執行上面的管道
let result = await p.exec();

操場

將以上代碼依次組合並測試。

暫無
暫無

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

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