MongoDB使用两个输入数组值执行$ match?

时间:2018-06-17 16:30:16

标签: arrays mongodb aggregation-framework

在MongoDB中,我正在尝试编写一个查询,其中我有两个输入数组BillsNames,其中第一个包含billid,第二个包含person的名称。实际上,索引i的索引和索引i的名称是我们想要在MongoDB中搜索的实际文档。

我想编写一个Bills[i] = db_billid && Names[i] = db_name的查询,这意味着我想在特定索引处返回结果,billid和name匹配。

我想过使用$in,但问题是我可以在$in中应用Bills,但我不知道找到billid的索引。

{ $and: [{ billid: { $in: Bills } }, {name: Names[**index at which this bill is found]}] }

任何人都可以帮助我如何解决这个问题?

MongoDB 架构

var transactionsschema = new Schema({
    transactionid: {type: String},
    billid: {type: String},
    name: {type: String}
});

MongoDB中的示例文档

{ _id: XXXXXXXXXXX, transactionid: 1, billid : bnb1234, name: "sudhanshu"}, { _id: XXXXXXXXXXX, transactionid: 2, billid : bnb1235, name: "michael"}, { _id: XXXXXXXXXXX, transactionid: 3, billid : bnb1236, name: "Morgot"}

示例数组

Bills = ["bill1", "bill2", "bill3"], Names = ["name1", "name2", "name"]

编辑 - 如果$ in可以在对象数组中工作,那么我可以使用带有键的对象数组作为billid和name

  

var arr = [{billid:“bill1”,“name”:“name1”},{billid:“bill2”,“name”:“name2”},{billid:“bill3”,“name”: “NAME3”}]

但事情就是如何放在查询

之下

{ $and: [{ billid: { $in: arr.Bills } }, {name: arr.Names}] }

1 个答案:

答案 0 :(得分:1)

知道bills是唯一的但names可能有重复项,您可以使用$indexOfArray获取匹配bill的索引,然后使用该索引来比较names在被评估的索引处使用数组(使用$arrayElemAt来检索值)。此外,您还必须检查$indexOfArray返回的值是否不等于-1(不匹配)

var bills = ["bnb1234", "bnb1235"];
var names = ["sudhanshu", "michael"];

db.col.aggregate([
    {
        $match: {
            $expr: {
                $and: [
                    { $ne: [{ $indexOfArray: [ bills, "$billid" ] }, -1] },
                    { $eq: ["$name", { $arrayElemAt: [ names, { $indexOfArray: [ bills, "$billid" ] } ] }] },
                ]
            }
        }
    }
])

$let可用于避免重复:

db.col.aggregate([
    {
        $match: {
            $expr: {
                $let: {
                    vars: { index: { $indexOfArray: [ bills, "$billid" ] } },
                    in: { $and: [ { $ne: [ "$$index", -1 ] }, { $eq: [ "$name", { $arrayElemAt: [ names, "$$index" ] }] }]}
                }
            }
        }
    }
])