MongoDB和Mongoose查询针对汇总$或具有不匹配字段的搜索返回null,返回单个搜索或省略未定义的值

时间:2018-10-24 22:00:31

标签: node.js mongodb express mongoose

我对在Mongoose / MongoDB查询中看到的行为感到有些困惑,因为似乎$or运算符被视为$and

我要查询以下收集文件:

{
    "_id": {
        "$oid": "5bd0d709ff8eef5d5325090f"
    },
    "audienceTrackingID": "3e66c213-fe0b-4096-a99c-558a6c349b4b",
    "mainframeTrackingID": null,
    "partner1TrackingID": "85c5f168-08da-44d3-bbef-fbb3b8392ded",
    "__v": 0,
    "contentFocus": "Cooking",
    "ipRange": [
        "29.142.127.151"
    ]
}

使用以下查询:

console.log(req.headers['x-original-ip']) // '29.142.127.151'
console.log(req.headers['x-audience-tracking-id']) // undefined
console.log(req.headers['x-partner-1-tracking-id']) // "85c5f168-08da-44d3-bbef-fbb3b8392ded"

const clientMatch = await Client.findOne({
    $or: [{ 
        ipRange: req.headers['x-original-ip'],  
        audienceTrackingID: req.headers['x-audience-tracking-id'],
        partner1TrackingID: req.headers['x-partner-1-tracking-id'],
    }]
})

console.log(clientMatch) // null

有些困惑,例如查询单个字段,以及在实际查询(req.headers['x-audience-tracking-id'])中未定义参数的情况下删除我的查询都会产生结果(这让我想知道,为什么这样做像AND并在一个查询字段失败时给我null?)

// ALL QUERIES HIT AND RETURN A MATCH:

const tryThis = await Client.findOne({partner1TrackingID: req.headers['x-partner-1-tracking-id']})
const ipMatch = await Client.findOne({ipRange: req.headers['x-original-ip']})
const clientMatch = await Client.findOne({
    $or: [{ 
        ipRange: req.headers['x-original-ip'],  
        partner1TrackingID: req.headers['x-partner-1-tracking-id'],
    }]
})

对我来说这没有意义。当其他字段匹配时,为什么我需要省略一个可能与$ or运算符不匹配的字段才能获得匹配?

1 个答案:

答案 0 :(得分:2)

当您尝试运行查询时,您实际上会得到:

query failed: cannot compare to undefined

请参见this here

这是您未获得结果的原因之一,另一原因是您的$or查询不正确。您需要将or-ed项分成MongoDB的单独对象:

因此将您的代码更改为此:

const clientMatch = await Client.findOne({
    $or: [
        {ipRange: req.headers['x-original-ip']},  
        {audienceTrackingID: req.headers['x-audience-tracking-id'] || ''},
        {partner1TrackingID: req.headers['x-partner-1-tracking-id']},
    ]
})