首页 > 解决方案 > 查找第二个集合的数组具有来自第一个集合的数组的单词

问题描述

我正在尝试做一个聚合,我想将一个数组中的项目关联到另一个数组。

这个想法是,获取与术语相关的句子,其中句子包含术语项中的所有单词。输出将是一个包含所有文本字段的项目和一个包含所有术语属性的自定义字段。

这是我的第一个收藏:

db.terms.insertMany([
  { "_id" : 1, "items" : ["sun", "day"] },
  { "_id" : 2, "items" : ["moon", "night"] },
])

第二个:

db.texts.insertMany([
  { "_id" : 1, "sentence" : ["a beautiful sun makes a bright day", "not usefull here"] },
])

意图聚合:

db.texts.aggregate([
    {$lookup: {
        from: "terms",
        let: { term_items: "$items" },
        pipeline: [
          { $match: { $expr: { "$sentence": { $all: "$$term_items" } } } }
        ],
        as: "term_obj"
    }},
]);

当我执行此聚合时,我收到此错误:

org.graalvm.polyglot.PolyglotException:命令失败,出现错误 168(InvalidPipelineOperator):服务器 localhost:27019 上的“无法识别的表达式“$$term_items”。完整的响应是 {"ok": 0.0, "errmsg": "Unrecognized expression '$$term_items'", "code": 168, "codeName": "InvalidPipelineOperator"}

另一个意图:

db.texts.aggregate([
    {$lookup: {
        from: "terms",
        let: { term_items: "$items" },
        pipeline: [
          { $match: { $expr: { $in: ["$$term_items", "$sentence"] } } }
        ],
        as: "term_obj"
    }},
]);

错误:

org.graalvm.polyglot.PolyglotException:命令失败,错误 40081(Location40081):'$in 需要一个数组作为第二个参数,发现:在服务器 localhost:27019 上丢失。完整的响应是 {"ok": 0.0, "errmsg": "$in 需要一个数组作为第二个参数,找到:missing", "code": 40081, "codeName": "Location40081"}

我在这里想念什么?

标签: mongodb

解决方案


在现有查找中,您正在使用$items它之前的值。$let 是您应该$sentence从外部文档分配给变量的地方。

完成此查找的一种可能解决方案:

  • $map 在sentence数组上
  • 对于每个句子,对items数组进行 $reduce 并使用$in
  • $reduce 在结果布尔数组上查看是否有一个句子匹配所有项目
  • 使用 $match 和 $expr 测试结果
db.texts.aggregate([
  {$lookup: {
      from: "terms",
      let: {sentences: "$sentence"},
      pipeline: [
        {$match: {
           $expr: {
             $reduce: {
               initialValue: false,
               input: {
                 $map: {
                   input: "$$sentences",
                   as: "sentence",
                   in: {$reduce: {
                        input: "$items",
                        initialValue: "true",
                        in: {$and: [
                            "$$value",
                            {$regexMatch: {
                                regex: "$$this",
                                input: "$$sentence"
                            }}
                        ]}
                   }}
                 }
               },
               in: {$or: ["$$this", "$$value"]}
             }
           }
       }}
     ],
     as: "term_obj"
  }}
])

操场


推荐阅读