2015-03-31 5 views
1

Ниже коллекция в MongoDBКаков правильный способ запроса в mongodb для массива документов?

{ 
"name" : "Tom" , 
"occupation" : "employee" , 
"data" : [ 
     { 
      "owns" : "Television" , 
      "company" : "xyz" 
     }, 
     { 
      "owns" : "Television" , 
      "company" : "abc" 
     }, 
     { 
      "owns" : "laptop" , 
      "company" : "abc" 
     } , 
     { 
      "owns" : "Television" , 
      "company" : "xyz" 
     } 

     ] 
} 

когда я запрашиваю

db.exp.find({"data.owns" : "Television"}) 

MongoDB возвращает документ, который имеет «владеет»: «ноутбук» в наборе результатов.

когда я запрашиваю

db.exp.find({"data.owns": "Television"},{_id: 0, data: {$elemMatch: {"owns": "Television"}}}) 

результат отображается только один документ из поля данных, где первый матч «Television» найден

Как мне запрос, чтобы получить все 3 документа, где Том владеет телевидения за исключением ноутбук документ. Ожидаемый результат

[ 
     { 
      "owns" : "Television" , 
      "company" : "xyz" 
     }, 
     { 
      "owns" : "Television" , 
      "company" : "abc" 
     }, 

     { 
      "owns" : "Television" , 
      "company" : "xyz" 
     } 

] 

Примечание: Я упомянул только 4 документов в поле данных в этом примере, где в качестве оригинала коллекции имеет более 50 документов. извините за мой бедный английский :).

ответ

1

Это может быть сделано с помощью aggregation.

  • $unwind в data массив.
  • Используйте $match этап для фильтрации документа, где owns значение равно Television.
  • этап $group, чтобы перегруппировать документ.
  • Этап $project, чтобы изменить форму документа.
db.exp.aggregate(
    [ 
     { "$unwind": "$data" }, 
     { "$match": { "data.owns": "Television" }}, 
     { 
      "$group": { 
          "_id": { 
            "name": "$name", 
            "occupation": "$occupation" 
           }, 
          "data": { "$push": "$data" } 
         } 
     }, 
     { 
      "$project": { 
          "name": "$_id.name", 
          "occupation": "$_id.occupation", 
          "data": 1, 
          "_id": 0 
         } 
     } 
    ] 
) 

Результат:

{ 
     "data" : [ 
       { 
         "owns" : "Television", 
         "company" : "xyz" 
       }, 
       { 
         "owns" : "Television", 
         "company" : "abc" 
       }, 
       { 
         "owns" : "Television", 
         "company" : "xyz" 
       } 
     ], 
     "name" : "Tom", 
     "occupation" : "employee" 
} 
1

Допустим, у вас есть два документа в коллекции exp

[ 
    { 
    "name" : "Tom" , 
    "occupation" : "employee" , 
    "data" : [ { "owns" : "Television" , "company" : "xyz" }, 
    { "owns" : "Television" , "company" : "abc" }, 
    { "owns" : "laptop" , "company" : "abc" } , 
    { "owns" : "Television" , "company" : "xyz" } ] 
    }, 
    { 
    "name" : "Jerry" , 
    "occupation" : "employee" , 
    "data" : [ { "owns" : "Mobile" , "company" : "xyz" }, 
    { "owns" : "Mobile" , "company" : "abc" }, 
    { "owns" : "laptop" , "company" : "abc" } , 
    { "owns" : "Laptop" , "company" : "xyz" } ] 
    } 
] 

Затем с вашим запросом db.exp.find({"data.owns" : "Television"}), вы получите

{ "_id" : 101, 
"name" : "Tom", 
"occupation" : "employee", 
"data" : [ 
    { "owns" : "Television", "company" : "xyz" }, 
    { "owns" : "Television", "company" : "abc" }, 
    { "owns" : "laptop", "company" : "abc" }, 
    { "owns" : "Television", "company" : "xyz" } 
] 
} 

Как первый документ имеет поля owns равные Television, то результатом будет полный первый документ. (включая те поля, которые имеют owns, кроме Television) Второй документ не будет часть результата, так как у него нет полей owns со значением Television.

$elemMatch вернет только один документ.

http://docs.mongodb.org/manual/reference/operator/projection/elemMatch/

Если вы хотите только те три объекта внутри массива, которые имеют Television в качестве своего значения, то вы можете использовать курсор, чтобы сохранить весь результат (в нашем случае только один документ) запроса.

var x = db.authors.find({"data.owns": "Television"},{_id: 0, "data.owns": 1}) 

И теперь использовать для каждого цикла, чтобы получить только те документы, которые имеют owns со значением Television.

+0

вместо фильтрации документов во внешнем приложении, не мы в состоянии выполнить эту задачу в самой базе данных? –

+0

Вы можете использовать агрегацию для этой цели. Извините, что я не упомянул в ответе. – Rajeshwar

Смежные вопросы