簡體   English   中英

MongoDB:僅返回與某個查詢匹配的數組中的文檔(JS)

[英]MongoDB: return just the document from an array that matches a certain query (JS)

我有一個 MongoDB 集合,格式如下:

users: {
    {
        user_id: 1000,
        activities: [
           {id: 1, activity: 'swimming'},
           {id: 2, activity: 'running'},
           {id: 3, activity: 'biking'},...
        ]
    },...
}

我想獲取與特定 ID 匹配的活動文檔。 例如,如果我使用{id: 1}進行查詢,我想要{id: 1, activity: 'swimming'}的輸出。 目前,我正在嘗試使用findOne({activities: {$elemMatch: {id: 1}}}) ,但它返回整個用戶文檔(用戶 ID 和所有活動)。

我正在使用的代碼是:

id = req.body.queryID;
db.collection('users').findOne({activities: {$elemMatch: {id}}})
    .then((document) => {
        console.log(document);
        // more code after this
    });

我也嘗試使用aggregate()findOne({}, {activities: {$elemMatch: {id}}})進行查詢,但我無法弄清楚。

根據db.version()我在 MongoDB 版本 4.4.8 上。 任何幫助表示贊賞!

您可以將aggregate方法與unwindmatchproject管道一起使用

db.users.aggregate([
    {$unwind: "$activities"},
    {$match: {"activities.id": id}},
    {$project: {id: "$activities.id", activity: "$activities.activity", _id: 0}}
])

注意:此代碼是使用 mongo shell 語法編寫的。

查詢執行以下操作

  1. unwind管道開始,它首先拉出活動數組中的所有項目。
  2. match管道找到具有我們正在尋找的 id 的數組元素
  3. project管道根據需要返回輸出

希望這可以幫助

請嘗試如下:

db.users.aggregate([
      {
        '$unwind': '$activities'
      }, {
        '$match': {
          'id': id
        }
      }, {
        '$project': {
          'activity': '$activities.activity', 
          'id': '$activities.id',
          '_id':0
        }
      }
    ]);

您的嘗試看起來很接近,我認為您只需要將它們放在一起即可。 findOne有兩個可選參數,一個查詢和一個投影。 該查詢告訴 MongoDB 查找並返回什么文檔。 投影文檔告訴 MongoDB 在查詢返回的文檔中包含哪些字段。

你在這里有什么:

db.collection('users').findOne({ activities: { $elemMatch: { id }}})

傳遞一個參數,即查詢。 它將查找一個文檔,其中activities數組中有一個元素的id等於變量id的值。 你也可以這樣寫:

db.collection('users').findOne({ "activities.id": id })

您還希望僅返回activities數組中具有匹配 ID 的文檔。 這是當您執行與其他嘗試類似的操作時,其中$elemMatch在第二個參數中,即投影:

db.collection('users').findOne({}, {activities: {$elemMatch: {id}}})

但是因為您傳遞了一個空查詢,MongoDB 將返回任何文檔,不一定是包含具有匹配 ID 的活動的文檔。

因此,如果您同時通過查詢和投影,我認為您應該得到您正在尋找的東西。 它可能看起來像這樣:

db.collection('users').findOne({ "activities.id": id }, { activities: { $elemMatch: { id }}})

這將僅包括_id字段和匹配的activities文檔(如果存在)。 如果要包含文檔的其他字段,則需要顯式包含它們。 請參閱有關投影的文檔

暫無
暫無

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

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