2014-08-30 15 views
11

Ürünler koleksiyonum var. Her ürün bir dizi ürün içerir.MongoDB koleksiyonunda verilen belge ve tek alt dokümanlar ile eşleşen ölçütler nasıl bulunur?

> db.products.find().pretty() 
{ 
    "_id" : ObjectId("54023e8bcef998273f36041d"), 
    "shop" : "shop1", 
    "name" : "product1", 
    "items" : [ 
      { 
        "date" : "01.02.2100", 
        "purchasePrice" : 1, 
        "sellingPrice" : 10, 
        "count" : 15 
      }, 
      { 
        "date" : "31.08.2014", 
        "purchasePrice" : 10, 
        "sellingPrice" : 1, 
        "count" : 5 
      } 
    ] 
} 

Yani, ben tarih ben parametre olarak sorgulamak için geçmesi bugüne kadar eşittir tek tek öğe ile tüm ürünleri almak için MongoDB sorgulayabilir nasıl, bana bir tavsiyede lütfen edebilirsiniz.

"31.08.2014" sonuç olmalıdır: Ne arıyorsun the positional $ operatörü ve "projeksiyon"

{ 
    "_id" : ObjectId("54023e8bcef998273f36041d"), 
    "shop" : "shop1", 
    "name" : "product1", 
    "items" : [ 
      { 
        "date" : "31.08.2014", 
        "purchasePrice" : 10, 
        "sellingPrice" : 1, 
        "count" : 5 
      } 
    ] 
} 
+0

'$ filter 'öğesini 3.2'den başlayarak kullanın. Daha fazla burada https://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection – Veeram

cevap

26

olduğunu.

db.products.find(
    { "items.date": "31.08.2014" }, 
    { "shop": 1, "name":1, "items.$": 1 } 
) 

Veya birden fazla eşleşen alan için $elemMatch:

db.products.find(
    { "items": { 
     "$elemMatch": { "date": "31.08.2014", "purchasePrice": 1 } 
    }}, 
    { "shop": 1, "name":1, "items.$": 1 } 
) 

tek alan için birden fazla alan kullanımı $elemMatch için, "nokta işaretini" kullanarak gerekli Dizi öğesi eşleşmesi gerekir Bunlar sadece bir dizi eleman için çalışır ve sadece bir tanesi iade edilir. Birden fazla dizi öğesinin koşullarınızdan döndürülmesini istiyorsanız, toplama çerçevesiyle daha gelişmiş işlemeye ihtiyacınız vardır.

db.products.aggregate([ 
    { "$match": { "items.date": "31.08.2014" } }, 
    { "$unwind": "$items" }, 
    { "$match": { "items.date": "31.08.2014" } }, 
    { "$group": { 
     "_id": "$_id", 
     "shop": { "$first": "$shop" }, 
     "name": { "$first": "$name" }, 
     "items": { "$push": "$items" } 
    }} 
]) 

Ya da belki Öğe dizi benzersiz girişler içeriyor MongoDB 2.6 beri kısa/hızlı biçimde

: $redact ile muhtemelen

db.products.aggregate([ 
    { "$match": { "items.date": "31.08.2014" } }, 
    { "$project": { 
     "shop": 1, 
     "name": 1, 
     "items": { 
      "$setDifference": [ 
       { "$map": { 
        "input": "$items", 
        "as": "el", 
        "in": { 
         "$cond": [ 
          { "$eq": [ "$$el.date", "31.08.2014" ] }, 
          "$$el", 
          false 
         ] 
        } 
       }}, 
       [false] 
      ] 
     } 
    }} 
]) 

Veya, ama biraz yapmacık:

db.products.aggregate([ 
    { "$match": { "items.date": "31.08.2014" } }, 
    { "$redact": { 
     "$cond": [ 
      { "$eq": [ { "$ifNull": [ "$date", "31.08.2014" ] }, "31.08.2014" ] }, 
      "$$DESCEND", 
      "$$PRUNE" 
     ] 
    }} 
]) 

Dolayısıyla, her zaman tek bir öğenin eşleşmesini veya birden çok öğeyi beklemesine bağlı olup, daha sonra hangi yaklaşımın daha iyi olduğuna bağlıdır. Ancak mümkün olduğunda .find() yöntemi, diğer işlemlerin genel yükünden yoksun olduğu için genellikle daha hızlı olacaktır.

Bir yan not olarak, "tarihleriniz", ileriye dönük çok iyi bir fikir olmayan dizeler olarak temsil edilir. Bunları, gelecekte size yardımcı olacak uygun Date nesne türlerine değiştirmeyi düşünün.

+0

Teşekkürler! Mükemmel cevap! Kesinlikle aradığım şey ve daha fazlası. – evgeniy44

+0

Teşekkür ederim. Bunu ayrıntılı olarak açıkladınız –

0

Mongo, alt sorgular için nokta gösterimini destekler.

Bkz: özellik genellikle sürücü bu gerektirmez bile, nokta gösterimde için tırnak içinde olduğunu

db.products.find({"items.date":"31.08.2014"}); 

Not: http://docs.mongodb.org/manual/reference/glossary/#term-dot-notation

senin sürücü bağlı olarak, böyle bir şey istiyorum.

İlgili konular