Мои данные очень динамичны c с возможностью добавления настраиваемых атрибутов и событий.
Вот как выглядит мой набор данных:
{
"_id" : ObjectId("5eccf898ac7ff694845f1ccf"),
"attributes" : [
{
"k" : "first_name",
"v" : "John"
},
{
"k" : "last_name",
"v" : "Doe"
},
{
"k" : "email",
"v" : "john.doe@example.net"
},
{
"k" : "gender",
"v" : "Male"
}
],
"events" : {
"event" : "add_to_cart",
"event_data" : [
{
"k" : "product_name",
"v" : "T-Shirt"
},
{
"k" : "price",
"v" : 25
},
{
"k" : "variants",
"v" : [
{
"k" : "color",
"v" : "red"
},
{
"k" : "size",
"v" : "xl"
},
{
"k" : "matherials",
"v" : [
[
{
"k" : "name",
"v" : "Cotton"
}
],
[
{
"k" : "name",
"v" : "Wool"
}
]
]
}
]
}
]
},
"created_at" : "2020-05-25 16:12:58",
"updated_at" : "2020-05-25 16:12:58"
}
Я определенно могу создать следующее index:
db.clients.ensureIndex({"events.event_data.k" : 1, "events.event_data.v" : 1 })
, и он отлично работает. Однако, если вы посмотрите на мой набор данных, вы заметите, что значения могут быть очень вложенными (например, материальные).
Этот запрос отлично работает:
db.clients.find({
"events.event_data": {
"$elemMatch": {
"k": "product_name",
"v": "T-Shirt"
}
}
})
в любом случае, когда я нужно запросить более глубокий уровень, тогда он сканирует весь размер. Вот как сканировать клиентов, которые купили хлопок футболку:
db.clients.find({
"events.event_data.v.v":
{
"$elemMatch": {
"$elemMatch" : {
"k": "name", "v": "Cotton"
}
}
}
})
Однако в этом случае он делает COLLSCAN , что, очевидно, мне бы хотелось. чтобы избежать?
Спасибо.
ps Я не хочу использовать подстановочный индекс, поскольку он не поддерживает сегментирование.