MongoDB 使用 Reduce 进行重复数据删除和排序

MongoDB Dedupe and Sort using Reduce

我正在使用 Reducearray.

创建 field 的连接 String

例如,假设我有一个 arraysubdocuments 称为 children - 每个 child 都有一个 name field .

例如

[
   {name:"Zak"}, {name:"Bob"}, {name:"Sharon"}, {name:"Zak"}, {name:"Cindy"}, {name:"Bob"}, {name:"Peter"}
]

下面的 expression 会给我一个 "Zak, Bob, Sharon, Zak, Cindy, Bob, Peter, ";

的“csv”

(是的 - 我知道我可以使用 $cond 来检测最后一次迭代并删除 trailing ", ".

  uniqueCsv: {
   $reduce: {
     input: "$children",
     initialValue: '',
     in: {
       $concat: ["$$this.name", ", ", "$$value"]
     }
   }
  }

是否可以用这个 reduce dedupesort 这样我们就可以

"Bob, Cindy, Peter, Sharon, Zak" ?

谢谢!

  • $setUnionchildren.name 中获取唯一元素,这将按升序对字符串进行排序
  • $concat 将第一个参数作为 $$value 传递,第二个作为条件传递,如果值为空,则 return 为空,否则为“,”,第三个作为 $$this 表示当前字符串
db.collection.aggregate([
  {
    $project: {
      uniqueCsv: {
        $reduce: {
          input: { $setUnion: "$children.name" },
          initialValue: "",
          in: {
            $concat: [
              "$$value",
              { $cond: [{ $eq: ["$$value", ""] }, "", ", "] },
              "$$this"
            ]
          }
        }
      }
    }
  }
])

Playground


第二种方法使用 $substr 而不是 $cond

  • $substr通过当前reduce操作,reduce操作会return, Bob, Cindy, Peter, Sharon, Zak
  • 现在我们只需要从上面的字符串中删除前 2 个字符,第二个参数从第二个位置开始字符串,第三个参数传递字符串长度 -1 将 return 所有字符串
db.collection.aggregate([
  {
    $project: {
      uniqueCsv: {
        $substr: [
          {
            $reduce: {
              input: { $setUnion: "$children.name" },
              initialValue: "",
              in: {
                $concat: ["$$value", ", ", "$$this"]
              }
            }
          },
          2,
          -1
        ]
      }
    }
  }
])

Playground

Warning:

As per MongoDB $setUnion: The order of the elements in the output array is unspecified.

but as per my experience it return array of string in ascending order, i have used it in my projects as well, i have tested it every way but it gives 100% ascending order.

It is your choice to use this in your project or not without mongodb confirmation.