Я пытаюсь сделать предложение $and
внутри предложения $match
. Это предложение $and
должно содержать полное сравнение со строкой, которую я предоставляю. Я хотел бы убедиться, что сравнение с attributes.value
должно соответствовать той строке, которую я передаю. Со следующим выражением:
db.getCollection('cards').aggregate([
{
"$match": {
'attributes.key': 'setCode',
'attributes.value': 'qc'
}
},
{
"$match": {
'attributes.key': 'code',
'attributes.value': 'potions'
}
}]);
Некоторые примеры данных, возвращаемых приведенным выше запросом:
[
{
"_id": {"$oid": "66ab6eec2982eff57de4423a"},
"attributes": [
{
"key": "name",
"displayText": "",
"value": "Weakness Potion",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "code",
"displayText": "",
"value": "weakness-potion",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "text",
"displayText": "",
"value": "To play this card, discard 1 of your Potions Lessons from play. Do 5 damage to your opponent. During your opponent's next turn, prevent all damage done to you by your opponent's Creatures.",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "illustrator",
"displayText": "",
"value": "Keith Garletts",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "orientation",
"displayText": "",
"value": "vertical",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "set",
"displayText": "",
"value": "Quidditch Cup",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "setCode",
"displayText": "",
"value": "qc",
"values": [],
"searchable": true,
"visible": false,
"language": ""
},
{
"key": "type",
"displayText": "",
"value": "Spell",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "typeCode",
"displayText": "",
"value": "spell",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "rarity",
"displayText": "",
"value": "Uncommon",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "rarityCode",
"displayText": "",
"value": "uncommon",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "lessonType",
"displayText": "",
"value": "Potions",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "lessonTypeCode",
"displayText": "",
"value": "potions",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "lessonCost",
"displayText": "",
"value": "7",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "actionCost",
"displayText": "",
"value": "1",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "cardNumber",
"displayText": "",
"value": "50",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "subType",
"displayText": "",
"value": "",
"values": [],
"searchable": true,
"visible": true,
"language": ""
}
],
"language": "en"
},
{
"_id": {"$oid": "66ab6eec2982eff57de4423d"},
"attributes": [
{
"key": "name",
"displayText": "",
"value": "Bruisewort Balm",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "code",
"displayText": "",
"value": "bruisewort-balm",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "text",
"displayText": "",
"value": "Shuffle up to 5 non-Healing cards from your discard pile into your deck.",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "illustrator",
"displayText": "",
"value": "Alex Horley",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "orientation",
"displayText": "",
"value": "vertical",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "set",
"displayText": "",
"value": "Quidditch Cup",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "setCode",
"displayText": "",
"value": "qc",
"values": [],
"searchable": true,
"visible": false,
"language": ""
},
{
"key": "type",
"displayText": "",
"value": "Spell",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "typeCode",
"displayText": "",
"value": "spell",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "rarity",
"displayText": "",
"value": "Common",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "rarityCode",
"displayText": "",
"value": "common",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "lessonType",
"displayText": "",
"value": "Potions",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "lessonTypeCode",
"displayText": "",
"value": "potions",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "lessonCost",
"displayText": "",
"value": "3",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "actionCost",
"displayText": "",
"value": "1",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "cardNumber",
"displayText": "",
"value": "53",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "subType",
"displayText": "",
"value": "",
"values": ["Healing"],
"searchable": true,
"visible": true,
"language": ""
}
],
"language": "en"
},
{
"_id": {"$oid": "66ab6eec2982eff57de44256"},
"attributes": [
{
"key": "name",
"displayText": "",
"value": "Potions",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "code",
"displayText": "",
"value": "potions",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "text",
"displayText": "",
"value": "Provides 1 Potions lesson.",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "illustrator",
"displayText": "",
"value": "Shanth Enjeti, Melissa Ferreira",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "orientation",
"displayText": "",
"value": "horizontal",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "set",
"displayText": "",
"value": "Quidditch Cup",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "setCode",
"displayText": "",
"value": "qc",
"values": [],
"searchable": true,
"visible": false,
"language": ""
},
{
"key": "type",
"displayText": "",
"value": "Lesson",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "typeCode",
"displayText": "",
"value": "lesson",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "rarity",
"displayText": "",
"value": "Common",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "rarityCode",
"displayText": "",
"value": "common",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "lessonType",
"displayText": "",
"value": "Potions",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "lessonTypeCode",
"displayText": "",
"value": "potions",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "actionCost",
"displayText": "",
"value": "1",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "cardNumber",
"displayText": "",
"value": "78",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "providesLesson",
"displayText": "",
"value": "Potions",
"values": [],
"searchable": true,
"visible": true,
"language": ""
},
{
"key": "subType",
"displayText": "",
"value": "",
"values": [],
"searchable": true,
"visible": true,
"language": ""
}
],
"language": "en"
}
]
Как видите, я получаю результаты, соответствующие коду, например potion
, potions
, cauldron potion
. Я также получаю результаты, в которых другие атрибуты с разными ключами содержат слово potions
.
Итак, мое предложение $match
не учитывает attributes.key
со значениями setCode
и code
, потому что оно сравнивается с другими атрибутами.
Как я могу убедиться, что приведенное выше условие $match
соответствует только заданным ключам и заданным значениям?
Спасибо всем!
Спасибо @aneroid, добавил несколько образцов результатов для дальнейшей проверки. Как, по вашему мнению, elemMatch будет работать с этим набором данных?
Добиться желаемых результатов можно, следуя предложению @aneroid с помощью $elemMatch
:
db.getCollection('cards').aggregate([{
"$match": {
"attributes": {
$elemMatch: {
key: "setCode",
value: "qc"
}
}
}
}, {
"$match": {
"attributes": {
$elemMatch: {
key: "code",
value: "potions"
}
}
}
}]);
Если кто-нибудь знает лучший способ добиться того же результата с помощью более простого запроса, дайте мне знать!
Как уже отмечал @aneroid, нет необходимости использовать $elemMatch
. Второй вариант его ответа должен быть «более простым запросом», который вы ищете.
Added a separate answer for the new example data.
Ответ на данные предыдущего примера:
Поскольку attributes
— это объект, а не массив полей «ключ-значение», вам не нужно делать attr.key
и attr.value
. (И вам также не понадобится $elemMatch для данных вашего примера.)
Используйте ключи и значения непосредственно в совпадении:
db.getCollection('cards').aggregate([
{
$match: {
"attributes.setCode": "qc",
"attributes.code": "potions"
}
}
])
И если вам не нужен конвейер агрегации для каких-то других шагов, его можно использовать непосредственно в запросе find
:
db.cards.find({
"attributes.setCode": "qc",
"attributes.code": "potions"
})
На самом деле я добавил правильный образец: предыдущий был с проекционным результатом, извините за это. Это массив в конце. С помощью elemMatch мне удалось добиться результатов. Посмотрите мой ответ ниже =)
Добавлен отдельный ответ для новых данных примера. Это становилось нечитабельным.
Для текущего примера данных используйте $elemMatch с $all:
db.cards.aggregate([
{
$match: {
"attributes": {
$all: [
{ $elemMatch: { "key": "setCode", "value": "qc" } },
{ $elemMatch: { "key": "code", "value": "potions" } }
]
}
}
}
])
И это также работает с find
:
db.cards.find({
"attributes": {
$all: [
{ $elemMatch: { "key": "setCode", "value": "qc" } },
{ $elemMatch: { "key": "code", "value": "potions" } }
]
}
})
Приведите примеры данных. Вероятно, вам придется использовать $elemMatch с
attributes
, иначе любая комбинация полей.key
и.value
с этим текстом будет совпадать.