2010-09-15 19 views
6

Linkler sahip bir veya daha fazla etiket, bu etiketleri gömmek için doğal görünebilir ilk başta: MongoDB'de bu sorguları verimli bir şekilde nasıl uygularsınız?

link = { title: 'How would you implement these queries efficiently in MongoDB?' 
     url: 'http://stackoverflow.com/questions/3720972' 
     tags: ['ruby', 'mongodb', 'database-schema', 'database-design', 'nosql']} 

Bunlar nasıl sorguları etkin bir şekilde uygulanacaktır ki?
  • (arama kutusu otomatik tamamlama için) tekrarlama olmadan tüm etiketlerin bir listesini alın (verilen etiketleri ile bağlantılar aramak için) bir veya birden fazla verilen etiketleri içeren

    • alın bağlantılar
    • En popüler etiketleri alma "değer" etiketi içeren linkler alın,

    yukarıdaki gibi MongoNY presentation dayanmaktadır bağlantıyı temsil etmek fikri (ilk 10 etiketleri veya bir etiket bulutu görüntülemek için) 38.

  • cevap

    4

    slayt :

    db.col.find({tags: "value"}); 
    

    "VAL1", "değer2" etiketleri içeriyor Al bağlantıları: tekrarlama olmadan tüm etiketlerin

    db.col.find({tags: { $all : [ "val1", "val2" ] }}); 
    

    al listesi:

    db.col.distinct("tags"); 
    

    en popüler etiketleri alma - Bu varolan bir db üzerinde sorgulanabilecek bir şey değil, yapmanız gereken şey bir sorguyu belgeyi getirdiğinde bir popülerlik alanı güncelleştirmesidir ve sonra sıralama alanı popülerliğe ayarlanmış bir sorguyu yapar.

    Güncelleştirme: popülerlik özelliği için önerilen çözüm. Aşağıdaki koleksiyonu eklemeyi deneyin, ona etiketleri diyelim.

    doc = {tag: String, pop: Tamsayı} şimdi bir sorgu (bu toplanabilir ve uyumsuz yapılabilir) gösterildi Tüm etiketleri toplamak o yüzden ne kadar son diyelim do kez

    aşağıdaki etiketler: "tag1", "tag2", "tag3".

    Daha sonra güncelleme yöntemini çağırın ve pop alan değeri artırmak:

    db.tags.update({tag: { $in: ["tag1", "tag2", "tag3"] }}, { $inc: { pop: 1 }}); 
    
    +0

    bir etiket için bir popülerlik alan eklemek için, etiketin doğru, ayrı bir koleksiyona eklenen veya taşınacak gerekir: Burada örneğidir? – randomguy

    +0

    yapmanıza gerek yok, aynı koleksiyonda saklayabilir ve etikete işaret etmek için sadece bir dbref kullanabilirsiniz. Farklı bir koleksiyon, verilerinizi yönetmenizi kolaylaştıracaktır (bunu tavsiye ederim). – Asaf

    +0

    Etiketler koleksiyonunda, etiket adını ayrı bir etiket alanı kullanmak yerine _id alanına koymanızı öneririz. Ayrıca, $ ini kullanmak yerine etiket başına bir güncelleme yapmayı düşünmüyorsanız, sorguyu yalnızca {_id: "tag_name"} yapabilir ve yeni etiket girişleri oluşturmak için upsert özelliğini kullanabilirsiniz. – mstearn

    0

    Ayrıca etiket dizisi yerine $ itmek değiştirmek için $ addToSet kullanabilirsiniz. Bu, etiket zaten mevcut olduğunda belgeyi değiştirmez. Etiketlerinizi sık sık değiştirdiğinizde (belgeler çok fazla büyümeyeceğinden) bu biraz daha verimli olacaktır.

    > db.tst_tags.remove() 
    > db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag1'}}, true) 
    > db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag1'}}, true) 
    > db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag2'}}, true) 
    > db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag2'}}, true) 
    > db.tst_tags.update({'name':'test'},{'$addToSet':{'tags':'tag3'}}, true) 
    > db.tst_tags.find() 
    { "_id" : ObjectId("4ce244548736000000003c6f"), "name" : "test", 
        "tags" : [ "tag1", "tag2", "tag3" ] } 
    
    İlgili konular