Сопоставить вложенный объект в документе с массивом возможных совпадений - PullRequest
0 голосов
/ 24 мая 2018

Мне нужно сопоставить вложенный объект в документе Mongo с массивом возможных совпадений.

Документы выглядят так:

{
  prop1: ...,
  prop2: ...,
  prop3: {
    p3a: 1,
    p3b: 7,
    p3c: 1051
  }
}

У меня есть массив потенциальных совпадений дляprop3:

[ { p3a: 1, p3b: 7, p3c: 1051 }, { p3a: x, p3b: y, p3c: z}, ... ]

Есть ли способ выполнить это сопоставление?Желательно использовать структуру агрегации, но даже если это возможно выполнить иначе, это все равно будет работать.

  • Нет способа изменить структуру модели, к ней привязано много старого кодак этому, так что даже если это не оптимально, я должен работать с ним или вокруг него.

1 Ответ

0 голосов
/ 24 мая 2018

Вы действительно не хотите агрегирования для этого, так как это означает, что вынуждает вычисление объединять совпадения.

Вместо этого вы хотите переназначить исходные данные из «неквалифицированных» имен ключей в «полностью определенные» имена ключей для использования в запросе.

Например:

 var arr = [ { p3a: 1, p3b: 7, p3c: 1051 }, { p3a: 'x', p3b: 'y', p3c: 'z'} ]

Может быть преобразовано:

 arr = arr.map(d => 
   Object.keys(d).reduce((o,k) => Object.assign(o, { [`prop3.${k}`]: d[k] }),{}));

Немного чище с JavaScript в стиле ES6, но оболочка mongo не поддерживает более новый синтаксис:

 arr = arr.map(d =>
   Object.entries(d).reduce((o,[k,v]) => ({ ...o, [`prop3.${k}`]: v }),{}) );

, который сейчас составляет список:

[
        {
                "prop3.p3a" : 1,
                "prop3.p3b" : 7,
                "prop3.p3c" : 1051
        },
        {
                "prop3.p3a" : "x",
                "prop3.p3b" : "y",
                "prop3.p3c" : "z"
        }
]

И теперь вы просто запрашиваете с $or:

db.collection.find({ $or: arr })

Так что это все, что вам нужно сделать, как $or принимает массив условий, и единственное, чего не хватает в вашем «списке», это то, что соответствующие ключи еще не имеют префикса с использованием «точечной нотации» для полного пути, включая "prop3".

Не существует такого понятия, как «предпочтение» для принудительного вычисления, когда обычный запрос, который может даже использовать индекс, если эти пути свойств не изменяются, будет выполнять работу эффективно и результативно

...