2015-02-23 17 views
11

MongoDB'nin find{array.0.field:"value"} sözdizimini desteklediğini biliyorum, ancak bunu özellikle dizideki son öğe için yapmak istiyorum, yani dizini bilmiyorum. Bunun için bir çeşit operatör var mı, yoksa şanstan mı kurtuldum?MongoDB - Bir dizinin son elemanında sorgulama var mı?

DÜZENLEME: Açıklığa kavuşturmak için, find() öğesini, bir dizinin son öğesindeki bir alanın belirli bir değerle eşleştiği belgeleri döndürmesini istiyorum.

+1

Belgeleriniz nasıl görünüyor? –

+0

Test etmeye çalıştığım dizi aslında başka bir dizinin içine yerleştirilmiş, ancak bunun bir etkisi olması gerektiğini düşünmüyorum. Temel olarak, yapmak istediğim şey, seçim seçicimde, sadece bir dizinin son elemanındaki belirli bir alanın belirli bir değere denk geldiği belgeleri döndürmektir. –

+0

[aggregation] 'a (http://docs.mongodb.org/manual/reference/operator/aggregation/) göz atmalı, ardından '$ unwind',' $ project', '$ match' ve' $ ile oynamalısınız. group' –

cevap

10

Resmi Mongo Google grubu here'a gönderildim ve çalışanlarından bir cevap aldım. Aradığım şeyin mümkün olmadığı anlaşılıyor. Ben sadece farklı bir şema yaklaşımı kullanacağım. Eğer $push ve sonra hep array.0 sorgulamak her

5

$ dilimini kullanın.

db.collection.find({}, { array_field: { $slice: -1 } }) 

Düzenleme: Bir eşleşme bulmak için { <field>: { $elemMatch: { <query1>, <query2>, ... } } } yararlanabilirler.

Ancak tam olarak aradığınız şeyi vermeyecektir. Henüz mongoDB'de mümkün olduğunu düşünmüyorum.

+0

Bu sadece son öğeyi döndürür, değil mi? Yapmaya çalıştığım şey bu değil.Bulucu seçicimin yalnızca dizinin son öğesinin belirli bir değerle eşleştiği belgeleri döndürmesini istiyorum. –

+0

Düzenleme sonrasında güncelleme eklendi. – Kaushal

4

Sen en son eklenen eleman almak için $position: 0 kullanabilirsiniz. Tabii ki, yeni "son" elemanını alamayacaksın.

+0

Bunu yapmayı düşündüm, ancak uygulama, bir dizinin önüne doğru itmeyi desteklemeyen Spring Data'yı kullanarak Mongo'ya erişiyor. Şimdi yapıp yapmadığından emin değilim. –

6
performansı hakkında emin

değil, ama bu benim için iyi çalışır: 3.2

db.getCollection('test').find(
    { 
    $where: "this.someArray[this.someArray.length - 1] === 'pattern'" 
    } 
) 
+0

$ nerede çok yavaş, çünkü javascript – eagleeye

+0

çalışır Çok teşekkür ederim! En performanslı çözüm olmayabilir, ama benim için bir çekicilik gibi çalışır. Verilerim için o kadar yavaş değil, belki de bu performans farkı sadece büyük veri setlerinde algılanabilir. –

9

bu mümkündür. İlk projem, böylece myField sadece son öğeyi içerir ve ardından myField ile eşleşir.

db.collection.aggregate([ 
    { $project: { id: 1, myField: { $slice: [ "$myField", -1 ] } } }, 
    { $match: { myField: "myValue" } } 
]); 
+0

Evet, mongodb 3.2 çalışıyor. 3.2'de – Kiran

+0

, negatif endekslerle çalışan $ arrayElemAt operatörü var. böylece bunun yerine {$ project: {id: 1, myField: {$ arrayElemAt: ["$ myField", -1]}}} 'olabilir. Tek bir öğeye sahip bir dilim aynı derecede verimli mi – makhdumi

+0

Bu sorunun tam olarak ne istediğini çıktılar. –

0

Düzenli sorguda toplama işlevlerini kullanmak $expr (3.6 Mongo versiyonu operatörünü) kullanabilir.

Karşılaştırın query operators vs aggregation comparison operators. sayıl diziler gömülü diziler için

db.col.find({$expr:{$gt:[{$arrayElemAt:["array", -1]}, value]}}) 

için

- Kullanım $let ifade alan değerini erişmek için nokta gösterimi ile son öğe proje.

db.col.find({$expr:{$gt:[{$let:{vars:{obj:{"$arrayElemAt": ["$array", 0]}},in: "$$obj.field"}}, value]}}) 

Yay @Query kod

@Query("{$expr:{$gt:[{$arrayElemAt:[\"array\", -1]}, ?0]}}") 
ReturnType MethodName(ArgType arg); 
0

Versiyon 3.6 kullanımı çekiş aynı ulaşmak için.

db.getCollection('deviceTrackerHistory').aggregate([ 
    { 
    $match:{clientId:"12"} 
    }, 
    { 
    $project: 
     { 
     deviceId:1, 
     recent: { $arrayElemAt: [ "$history", -1 ] } 
     } 
    } 
]) 
İlgili konular