猫鼬查询文档匹配数组,无论其元素顺序如何

时间:2019-01-27 23:33:21

标签: mongodb mongoose mongodb-query

使用MongoDB / Mongoose,考虑我的test集合具有以下2个文档:

"_id" : ObjectId("5c4e3cef9cd12904cfc7ecc0"),
"name" : "REGISTER1",
"properties" : [
        {
            "property” : "PROP1",
            "value" : "GREEN"
        },
        {
            "property” : "PROP2",
            "value" : "RED"
        }
    ]

"_id" : ObjectId("5c4e3cef9cd12904cfc7ecc0"),
"name" : "REGISTER2",
"properties" : [
        {
            "property" : "PROP2",
            "value" : "RED"
        },
        {
            "property" : "PROP1",
            "value" : "GREEN"
        }
    ]

我正在使用以下命令查找寄存器:

db.tests.find(
   { properties: [
            {
                "property" : "PROP2",
                "value" : "RED"
            },
            {
                "property" : "PROP1",
                "value" : "GREEN"
            }
        ]
   }).pretty();

返回REGISTER2,而不返回REGISTER1

以相同的方式:

db.tests.find(
   { properties: [
            {
                "property" : "PROP1",
                "value" : "GREEN"
            },
            {
                "property" : "PROP2",
                "value" : "RED"
            }
        ]
   }).pretty();

返回REGISTER1,而不返回REGISTER2

我需要两个查询来同时返回元素“ REGISTER1”和“ REGISTER2”,因为之间的唯一变化是属性顺序(数组顺序)。

无论查询元素的排列顺序如何,如何查询都返回REGISTER1REGISTER2

2 个答案:

答案 0 :(得分:1)

您可以为此使用$all查询:

db.tests.find({
  properties: {$all: [
   {property: 'PROP1', value: 'GREEN'},
   {property: 'PROP2', value: 'RED'} 
]}})

$all的两个元素都必须存在才能使文档匹配,但是顺序无关紧要。

对于properties元素除了要匹配的内容之外还包含更多键的情况,可以使用$elemMatch

db.tests.find({
  properties: {$all: [
   {$elemMatch: {property: 'PROP1', value: 'GREEN'}},
   {$elemMatch: {property: 'PROP2', value: 'RED'}} 
]}})

$elemMatch确保每个property / value元组都匹配相同的元素。

答案 1 :(得分:0)

第一个文档的属性名称为property_id,第二个文档的属性名称为property

请使用$elemMatch$or来获取两个匹配的文档

db.tests.find({
    properties : {$elemMatch : {$or : [
        {"property" : "PROP1", "value" : "GREEN"},
        {"property" : "PROP2", "value" : "RED"}
    ]}}
})

样品采集

> db.tests.find()
{ "_id" : ObjectId("5c4e3cef9cd12904cfc7ecc0"), "name" : "REGISTER1", "properties" : [ { "property" : "PROP1", "value" : "GREEN" }, { "property" : "PROP2", "value" : "RED" } ] }
{ "_id" : ObjectId("5c4e3cef9cd12904cfc7ecc1"), "name" : "REGISTER2", "properties" : [ { "property" : "PROP2", "value" : "RED" }, { "property" : "PROP1", "value" : "GREEN" } ] }

找到

> db.tests.find({properties : {$elemMatch : {$or : [{"property" : "PROP1", "value" : "GREEN"},{"property" : "PROP2", "value" : "RED"}]}}})
{ "_id" : ObjectId("5c4e3cef9cd12904cfc7ecc0"), "name" : "REGISTER1", "properties" : [ { "property" : "PROP1", "value" : "GREEN" }, { "property" : "PROP2", "value" : "RED" } ] }
{ "_id" : ObjectId("5c4e3cef9cd12904cfc7ecc1"), "name" : "REGISTER2", "properties" : [ { "property" : "PROP2", "value" : "RED" }, { "property" : "PROP1", "value" : "GREEN" } ] }
>