Находит все документы, в которых поле массива содержит документ, соответствующий некоторым условиям

У меня есть коллекция MongoDB, в которой хранятся все пользовательские данные.

Документ моей коллекции имеет следующую форму JSON:

{
    "_id" : ObjectId("542e67e07f724fc2af28ba75"),
    "id" : "",
    "email" : "[email protected]",
    "tags" : [
        {
            "tag" : "Paper Goods:Liners - Baking Cups",
            "weight" : 2,
            "lastInsert" : 1412327492874
        },
        {
            "tag" : "Vegetable:Carrots - Jumbo",
            "weight" : 4,
            "lastInsert" : 1412597883569
        },
        {
            "tag" : "Paper Goods:Lialberto- Baking Cups",
            "weight" : 1,
            "lastInsert" : 1412327548205
        },
        {
            "tag" : "Fish:Swordfish Loin Portions",
            "weight" : 3,
            "lastInsert" : 1412597939124
        },
        {
            "tag" : "Vegetable:Carrots - [email protected]",
            "weight" : 2,
            "lastInsert" : 1412597939124
        }
    ]
}

Поле tag имеет форму "category:name product", а поле "tags" содержит все продукты, купленные пользователем.

Я пишу приложение Scala и использую драйвер reactivemongo. Теперь я пишу метод, который с учетом category и product ищет всех пользователей, которые купили хотя бы продукт данной категории, но еще не купили ни одного продукта, равного данному.

Мой код сейчас выглядит следующим образом:

def findUsers(input: FindSuggestion): Future[Option[List[User]]] = {
      val category = input.category //a string
      val product = input.product  //a string, in the form category:productName
      val query = Json.obj(//create the query object)
      Users.find(query).toList.flatMap(users =>
        if(users.size > 0)
          Future{Some(users)}
        else
          Future{None}
          )
    }

Чтобы быть более конкретным, я ищу весь документ, где поле tags содержит документ, где поле tag начинается с категории, но поле tags не содержит документа, где tag == product.

Как я могу сделать это в mongodb ??


person alberto adami    schedule 20.10.2014    source источник


Ответы (1)


Для эффективного запроса вы должны изменить структуру документов, например, как

{
    "_id" : ObjectId("542e67e07f724fc2af28ba75"),
    "id" : "",
    "email" : "[email protected]",
    "tags" : [
        {
            "category": "Fish",
            "product": "Swordfish Loin Portions"
            "weight" : 2,
            "lastInsert" : 1412327492874
        },
        {
            "category": "Vegetable",
            "product": "Carrots - Jumbo",
            "weight" : 4,
            "lastInsert" : 1412597883569
        }
    ]
}

И создайте индекс по категории и продукту.

Запрос будет

$and:[{"tags.category":"requestedCategory"},{$ne:{"tags.product":"requestedProduct"}}]

И если вы решите не изменять структуру, запрос

$and:[{"tags.tag":$regex: 'requestedCategory:.*'},{$ne:{"tags.tag":"requestedCategory:requestedProduct"}}]

Обновлять. Добавление индекса

db.collection.ensureIndex( { "tags.tag": 1 } )
person sh1ng    schedule 20.10.2014
comment
Привет, спасибо за ваш ответ. Я не могу изменить структуру своих документов. Я хотел бы ответить вам, как указать индексы на mongodb в этом случае?? Я еще не использовал индекс в mongodb. - person alberto adami; 20.10.2014
comment
Синтаксис запросов неверен. Запросы должны быть { "tags.category" : "requestedCategory", "tags.product" : { "$ne" : "requestedProduct" } } и { "tags.tag" : { "$regex" : "Paper Goods:.*" }, "tags.tag" : { "$ne" : "Paper Goods:Lialberto- Dunking Cups" } } соответственно. Абсолютно измените структуру документа, как указано в ответе. Почему ты не можешь это изменить? все, что вам нужно сделать, это добавить поля, которые сделают поиск проще и эффективнее. - person wdberkeley; 20.10.2014
comment
Спасибо за комментарий, я ошибся в названии поля. Но я думаю, что ваш запрос дает тот же результат, что и мой. - person sh1ng; 20.10.2014
comment
Я не могу изменить структуру, потому что в коллекции @wdberkeley много данных. Я не создавал эту структуру, я работаю над проектом с такой структурой. - person alberto adami; 21.10.2014