Используя 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», поскольку единственное изменение между ними — это порядок свойств (порядок массива).
Как я могу запросить возврат как REGISTER1
, так и REGISTER2
, независимо от порядка элементов запроса в массиве?
🤔 А знаете ли вы, что...
MongoDB является открытым исходным кодом и доступна под лицензией GNU AGPL...
Имя свойства в первом документе — 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" } ] }
>
Для этого вы можете использовать запрос $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
соответствует одному и тому же элементу.