2014-12-14 3 views
1

Я пытаюсь найти объекты с помощью встроенного опрашивает и это просто не работает .. Мой файл JSON-то вроде этого:объекты Поиск JSON в MongoDB

{ "Text1": 
    { 
     "id":"2" 
    }, 
    "Text2": 
    { 
     "id":"2,3" 
    }, 
    "Text3": 
    { 
     "id":"1" 
    } 
} 

И я пишу этот db.myCollection.find({"id":2}) И ничего не находит. Когда я пишу db.myCollection.find(), он показывает все данные так, как должен.

Кто-нибудь знает, как это сделать правильно?

+0

Генетического запроса для вашей структуры данных нет. В любом случае используйте db.b.find ({$ или: [{"Text1.id": '2'}, {"Text2.id": '2'}, {"Text3.id": '2'}]}) – Disposer

+0

дает мне неожиданный токен:. что вы имеете в виду. Генриальный запрос для вашей структуры данных отсутствует? Разве это не то, как вы пишете json. Я видел его онлайн много раз – asdsd

+0

Что вы ожидали от своего результата? – Disposer

ответ

3

Сложно изменить структуру данных, но, как вы хотите, только ваш соответствующий суб-документ, и вы не знаете, где находится ваш целевой документ (например, запрос должен быть на или Text2, ...) там хорошая структура данных для этого:

{ 
    "_id" : ObjectId("548dd9261a01c68fab8d67d7"), 
    "pair" : [ 
     { 
      "id" : "2", 
      "key" : "Text1" 
     }, 
     { 
      "id" : [ 
       "2", 
       "3" 
      ], 
      "key" : "Text2" 
     }, 
     { 
      "id" : "1", 
      "key" : "Text3" 
     } 
    ] 
} 

и ваш запрос:

db.myCollection.findOne({'pair.id' : "2"} , {'pair.$':1, _id : -1}).pair // there is better ways (such as aggregation instead of above query) 

в результате вы будете иметь:

{ 
    "0" : { 
     "id" : "2", 
     "key" : "Text1" 
    } 
} 

Update 1 (новичку путь)

Если вы хотите, чтобы все документы не только один использовать этот

var result = []; 
db.myCollection.find({'pair.id' : "2"} , {'pair.$':1, _id : -1}).forEach(function(item) 
{ 
    result.push(item.pair); 
}); 

// the output will be in result 

Update 2

Используйте этот запрос, чтобы получить все поддокументы

db.myCollection.aggregate 
(
    { $unwind: '$pair' }, 
    { $match : {'pair.id' : "2"} } 
).result 

он производит выход как

{ 
    "0" : { 
     "_id" : ObjectId("548deb511a01c68fab8d67db"), 
     "pair" : { 
      "id" : "2", 
      "key" : "Text1" 
     } 
    }, 
    "1" : { 
     "_id" : ObjectId("548deb511a01c68fab8d67db"), 
     "pair" : { 
      "id" : [ 
       "2", 
       "3" 
      ], 
      "key" : "Text2" 
     } 
    } 
} 
+0

Благодарим вас за помощь, но разве нет пути (структуры), в котором я мог бы извлечь данные, используя db.myCollection.find ({"Text1.id": "2"}). Я видел это также в Интернете в качестве ответов – asdsd

+0

, поскольку @styvane soukossi ответил, да, вы можете, но вы должны знать свое целевое поле, которое в данном случае является «Text1.id» – Disposer

+0

Я знаю, если бы он работал, я бы изменил мою структуру, поэтому я подойду, но это не сработало. – asdsd

2

Поскольку ваш запрос указывает поле в поддокументе, это то, что будет работать. см. документацию .find().

db.myCollection.find({"Text1.id" : "2"}, {"Text1.id": true}) 
{ "_id" : ObjectId("548dd798e2fa652e675af11d"), "Text1" : { "id" : "2" } } 

Если запрос на «Text1» или «Текст2» лучшая вещь, чтобы сделать здесь, как упоминание в принятом ответе меняется документировать структуру. Это можно легко сделать, используя API "Bulk".

var bulk = db.mycollection.initializeOrderedBulkOp(), 
    count = 0; 

db.mycollection.find().forEach(function(doc) { 
    var pair = []; 
    for(var key in doc) {  
     if(key !== "_id") { 
      var id = doc[key]["id"].split(/[, ]/); 
      pair.push({"key": key, "id": id}); 
     } 
    } 
    bulk.find({"_id": doc._id}).replaceOne({ "pair": pair }); 
    count++; if (count % 300 == 0){ 
     // Execute per 300 operations and re-Init 
     bulk.execute();  
     bulk = db.mycollection.initializeOrderedBulkOp(); 
    } 
}) 

// Clean up queues 
if (count % 300 != 0) 
    bulk.execute(); 

Ваш документ выглядеть следующим образом:

{ 
     "_id" : ObjectId("55edddc6602d0b4fd53a48d8"), 
     "pair" : [ 
       { 
         "key" : "Text1", 
         "id" : [ 
           "2" 
         ] 
       }, 
       { 
         "key" : "Text2", 
         "id" : [ 
           "2", 
           "3" 
         ] 
       }, 
       { 
         "key" : "Text3", 
         "id" : [ 
           "1" 
         ] 
       } 
     ] 
} 

Запуск следующий запрос:

db.mycollection.aggregate([ 
    { "$project": { 
     "pair": { 
      "$setDifference": [ 
       { "$map": { 
        "input": "$pair", 
        "as": "pr", 
        "in": { 
         "$cond": [ 
          { "$setIsSubset": [ ["2"], "$$pr.id" ]}, 
          "$$pr", 
          false 
         ] 
        } 
       }}, 
       [false] 
      ] 
     } 
    }} 
]) 

возвращается:

{ 
     "_id" : ObjectId("55edddc6602d0b4fd53a48d8"), 
     "pair" : [ 
       { 
         "key" : "Text1", 
         "id" : [ 
           "2" 
         ] 
       }, 
       { 
         "key" : "Text2", 
         "id" : [ 
           "2", 
           "3" 
         ] 
       } 
     ] 
} 
Смежные вопросы