Как отфильтровать по подстроке под-документа, используя $ indexOfCP? - PullRequest
0 голосов
/ 29 января 2020

Как мне вернуть записи из моей коллекции "greesthings", где у "вещей" нет указанной подстроки c?

{
    "_id" : ObjectId("5d24e6e5e8b6b11536a8519b"),
    "message" : "hello",
    "meta" : {
        "info" : "friendly score 923",
        "things" : "cat bat dragon",
    }
},
{
    "_id" : ObjectId("5d24e6e5e8b6b11536a8519c"),
    "message" : "hello",
    "meta" : {
        "info" : "confused score 622",
        "things" : "cat monkey dragon",
    }
}

Я пытаюсь запросить / отфильтровать все записи 'hello message' {$match:{ message: { $eq: 'hello' }}} по подстроке в meta.things

И сравнивая подстроку Обезьяна до meta.things для фильтрации результатов

Когда я пытаюсь этот $ filter , он выдает ошибку "errmsg" : "input to $filter must be an array not object"

db.getCollection('greetsthings').aggregate( 
[{$match:{ message: { $eq: 'hello' }}},
 {$project: {
    message: 1,
    "meta": {
       $filter: {$gte : [{$indexOfCP: ["$meta.things", "monkey"]},0]}
          }
       } 
    }
])

Как я могу вернуть только записи, в которых сообщение привет и обезьяна в строке meta.things?

Ответы [ 2 ]

1 голос
/ 30 января 2020

У вас ошибка "синтаксиса" с "$meta.things". $ expr позволяет вычислять операции с полями документа:

db.greetsthings.aggregate([
  {
    $match: {
      $expr: {
        $and: [
          {
            $eq: [
              "$message",
              "hello"
            ]
          },
          {
            $gt: [
              {
                $indexOfCP: [
                  "$meta.things",
                  "monkey"
                ]
              },
              -1
            ]
          }
        ]
      }
    }
  }
])

MongoPlayground

А также отрицание, как я могу вернуть записи, где сообщение привет, но дракона нет в строке meta.things?

Ищет строку для вхождения подстроки и возвращает индекс кодовой точки UTF-8 (основанный на нуле ) первого появления. Если подстрока не найдена, возвращается -1 .

https://docs.mongodb.com/manual/reference/operator/aggregation/indexOfCP/

$eq: [
  {
    $indexOfCP: [
      "$meta.things",
      "dragon"
    ]
  },
   -1
]
1 голос
/ 30 января 2020

Пожалуйста, попробуйте это:

db.getCollection('greetsthings').aggregate(
    [{ $match: { message: 'hello' } },
    {
        $addFields: {
            shouldExists: { $gte: [{ $indexOfCP: ['$meta.things', "monkey"] }, 0] }, // Adds try if word monkey exists in string
            shouldNotExists: { $gte: [{ $indexOfCP: ['$meta.things', "dragon"] }, 0] } // Adds try if word dragon exists in string
        }
    }, { $match: { shouldExists: true, shouldNotExists: false } },
    { $project: { shouldExists: 0, shouldNotExists: 0 } }
    ])

Тест: MongoDB-Playground

...