簡體   English   中英

使用預先未知的方面執行搜索 Atlas MongoDB

[英]Perform search with facets unknown upfront Atlas MongoDB

我在MongoDB中有如下文檔結構:

{
  // other keys,
  tags: [
    tagA: "red",
    tagB: "green"
  ]
},
{
  // other keys,
  tags: [
    tagA: "orange",
    tagB: "green",
    tagC: "car"
  ]
}

我想執行 $facets 搜索,得到以下 output(每個標簽的名稱 + 該標簽上出現的值 + 這些值的計數):

{
  [
    tagA: {
      red: 1,
      orange: 1
    },
    tagB: {
      green: 2
    },
    tagC: {
      car: 1
    }
  ]   
}

棘手的部分是這些方面是預先未知的(它們可能會有所不同),而且我發現的每個教程都只適用於一組預定義的方面。

是否可以?

PS:如何讓這個 output 與給定的查詢一起出現? 所以回報是這樣的:

{
  queryResults: [all the results, as in a normal query],
  facets: [result showed in accepted answer]
}

如果您考慮將此作為輸入(我在您的數組中添加了圍繞 object 的括號):

[
  {
    tags: [
      {
        tagA: "red"
      },
      {
        tagB: "green"
      }
    ]
  },
  {
    tags: [
      {
        tagA: "orange"
      },
      {
        tagB: "green"
      },
      {
        tagC: "car"
      }
    ]
  }
]

然后,您可以按如下方式執行聚合管道:

db.collection.aggregate([
  {
    "$unwind": "$tags"
  },
  {
    "$addFields": {
      "kv": {
        "$objectToArray": "$tags"
      }
    }
  },
  {
    "$unwind": "$kv"
  },
  {
    "$group": {
      "_id": {
        key: "$kv.k",
        value: "$kv.v"
      },
      "count": {
        "$sum": 1
      }
    }
  },
  {
    "$group": {
      "_id": "$_id.key",
      "value": {
        "$push": {
          "k": "$_id.value",
          "v": "$count"
        }
      }
    }
  },
  {
    $project: {
      val: [
        {
          k: "$_id",
          v: {
            "$arrayToObject": "$value"
          }
        }
      ]
    }
  },
  {
    $project: {
      res: {
        "$arrayToObject": "$val"
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: "$res"
    }
  }
])

它會給你這個結果:

[
  {
    "tagA": {
      "orange": 1,
      "red": 1
    }
  },
  {
    "tagB": {
      "green": 2
    }
  },
  {
    "tagC": {
      "car": 1
    }
  }
]

您可以在 mongoplayground 上看到這個: https://mongoplayground.net/p/FZbM-BGJRBm希望這能回答您的問題。

詳細解釋:

  1. 我在tags字段上使用$unwind以便在標簽數組中為每個 object 獲得一個 object。
  2. 我使用$objectToArray objectToArray 獲取鍵( tagsAtagsB )作為值。
  3. $unwind到 go 從數組到對象。
  4. $group$sum累加器來計算每個唯一組合的出現。
  5. $group by tagsA , tagsB , etc with $push accumulator 在數組中添加值(之后將被使用)
  6. $arrayToObject到 go 從數組到 object
  7. 相同的
  8. $replaceRoot以更好地顯示結果。

如果您想了解更多每個步驟,請考慮閱讀我使用的每個管道聚合器的 mongo 文檔。 您也可以使用上面的 mongoplayground 鏈接,刪除一些代碼以查看每一步之后會發生什么。

暫無
暫無

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

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