【问题标题】:How to do a full match search with two parameters?如何使用两个参数进行完全匹配搜索?
【发布时间】:2020-03-12 17:58:51
【问题描述】:

我有数据库模型

Schema({
  members: [
    {
      type: String,
      required: true,
      ref: "User"
    }
  ],
  createdAt: {
    type: Date,
    default: Date.now(),
    required: true
  },
  lastMessage: {
    message: {
      type: String,
      required: true
    },
    from: {
      type: String,
      required: true
    },
    createdAt: {
      type: Date,
      required: true
    }
  },
  messages: [
    {
      createdAt: {
        type: Date,
        required: true
      },
      message: {
        type: String,
        required: true
      },
      from: {
        type: String,
        ref: "User",
        required: true
      }
    }
  ]
});

我用来查找一些文档的代码

Chats.countDocuments(
      {
        members: {
          $in: ["userIdOne", "userIdTwo"]
        }
      },
      cb
    )

我使用$in 查找我需要的数据,但$in 查找包含此userId... 之一的所有文档。我只需要找到一个包含该用户 ID 的文档。

我该怎么做?

【问题讨论】:

    标签: javascript mongodb mongoose mongodb-query


    【解决方案1】:

    改用$all

    Chats.countDocuments(
      {
        members: {
          $all: ["userIdOne", "userIdTwo"]
        }
      },
      cb
    )
    

    【讨论】:

    • @bpGusar 如果您需要完全匹配,这个答案可能会给出错误的结果。见playgound。它还将文档与成员 ["userIdOne", "userIdTwo","userIdThree"] 匹配
    • @Valijon 是的,你是对的,但提及这一点并没有什么坏处
    • @bpGusar 如果此答案解决了您的问题,请不要忘记将其标记为答案。
    【解决方案2】:

    如果需要精确匹配,可以使用$setEquals聚合运算符。

    db.collection.aggregate([
      {
        $match: {
          $expr: {
            $eq: [
              {
                $setEquals: [
                  "$members",
                  [
                    "userIdOne",
                    "userIdTwo"
                  ]
                ]
              },
              true
            ]
          }
        }
      },
      {
        $count: "count"
      }
    ])
    

    输入:

    [
      {
        "members": [
          "userIdOne"
        ]
      },
      {
        "members": [
          "userIdTwo"
        ]
      },
      {
        "members": [
          "userIdOne",
          "userIdTwo"
        ]
      },
      {
        "members": [
          "userIdOne",
          "userIdTwo",
          "userIdThere"
        ]
      }
    ]
    

    输出:

    [
      {
        "count": 1
      }
    ]
    

    Playground

    您可以像这样将它集成到猫鼬中:

      const result = await Chats.aggregate([
        {
          $match: {
            $expr: {
              $eq: [
                {
                  $setEquals: ["$members", ["userIdOne", "userIdTwo"]]
                },
                true
              ]
            }
          }
        },
        {
          $count: "count"
        }
      ]);
    
      const count = result[0].count;
    

    【讨论】:

    • $setEquals 有一些这样的缺陷:{ $setEquals: [ [ "a", "b", "a" ], [ "b", "a" ] ] } => true
    • @Valijon 谢谢你的指点。但我猜 userId 不会有重复值。
    猜你喜欢
    • 2016-10-15
    • 2023-03-09
    • 2019-01-09
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 2020-04-18
    • 2011-12-19
    • 1970-01-01
    相关资源
    最近更新 更多