2014-07-23 3 views
1

J'essaie de trier les valeurs après l'exécution d'une recherche sur mon API MongoDB by Java. La liste des résultats contient les entrées suivantes:MongoDB, Java, tri par première entrée de tableau

{ 
"_id": "P17-223", 
"property": "P17", 
"itemid": 223, 
"labels": [ 
    { 
    "language": "en", 
    "value": "Greenland" 
    }, 
    { 
    "language": "es", 
    "value": "Groenlandia" 
    }, 
    { 
    "language": "de", 
    "value": "Grönland" 
    } 
] 

}

Je veux trier par la première entrée du tableau étiquettes:

DBCursor cursor = getCollection().find(query); 
    BasicDBObject orderBy = new BasicDBObject("labels[0].value", 1); 
    cursor.sort(orderBy); 

valeurs du curseur ne sont pas triés par ce code . Pouvez-vous m'aider?

+1

Il pourrait être beaucoup plus facile de régler ce problème dans le code Java que sur la couche MongoDB. Est-ce que cela vous convient, ou insistez-vous pour le trier dans la base de données? – Philipp

+0

Le tri en Java est correct, sauf si vous avez besoin d'interroger un grand nombre de documents – injecteer

+1

Avez-vous essayé BasicDBObject orderBy = new BasicDBObject ("labels.0.value", 1); – Mike

Répondre

1

Vous ne pouvez pas réellement "trier" par un index spécifique d'un tableau dans un document dans MongoDB. ct Si vous devez vraiment le faire, vous avez besoin du aggregation framework pour "extraire" l'élément à trier.

Je sais que le formulaire de liste est réellement obsolète, donc ce code est juste pour la démonstration. définir acutally votre pipeline en tant que variables individuelles et nourrir ceux comme argument pour agréger:

BasicDBList pipeline = new BasicDBList(); 
    list.add(new BasicDBObject("$unwind","$labels")); 
    list.add(new BasicDBObject("$group", 
     new BasicDBObject("_id","$_id") 
      .append("property", new BasicDBObject("$first","$property")) 
      .append("itemid", new BasicDBObject("$first","$itemid")) 
      .append("labels", new BasicDBObject("$push","$labels")) 
      .append("maxLabel", new BasicDBObject("$max", "$labels.value")) 
    )); 
    list.add(new BasicDBObject("$sort", new BasicDBObject("maxLabel",1))); 

    System.out.println(pipeline); 

Cela vous donne la version sérialisée qui est la forme JSON de:

db.collection.aggregate([ 
    { "$unwind" : "$labels" }, 
    { "$group": { 
     "_id": "$_id", 
     "property": { "$first" : "$property" }, 
     "itemid": { "$first" : "$itemid" }, 
     "labels": { "$push" : "$labels" }, 
     "maxLabel": { "$max" : "$labels.value"} 
    }}, 
    { "$sort" : { "maxLabel" : 1} } 
]) 

mieux appliquée dans votre code comme:

collection.aggregate(unwind,group,sort); 

Lorsque ceux-ci sont déclarés individuellement.

+0

Merci Neil, puh ... compliqué;) Merci Philipp, je vais essayer de trier les éléments dans le code Java. –

5

Avez-vous essayé

BasicDBObject orderBy = new BasicDBObject("labels.0.value", 1); 

Il est pas évident, mais la documentation MongoDB échappe à elle. L'utilisation du signe $ correspond au premier élément, mais la spécification du numéro d'élément de tableau semble fonctionner. Si quelqu'un a un meilleur document décrivant le comportement, s'il vous plaît répondez avec le lien.

De la documentation

Documents de mise à jour dans un tableau

The positional $ operator facilitates updates to arrays that contain embedded 
documents. Use the positional $ operator to access the fields in the embedded 
documents with the dot notation on the $ operator. 

db.collection.update({ <query selector> }, { <update operator>: { "array.$.field" : value } }) 


Documentation est here