2012-09-08 2 views
1

J'ai un scénario où les documents sont indexés dans la recherche élastique, et j'ai besoin de récupérer le document correspondant dans mongo avec les documents précédents et suivants triés par un horodatage. L'idée étant de récupérer le contexte du document avec le document original.Récupération d'un document séquentiel basé sur _id

Je suis capable de le faire avec succès maintenant si j'utilise un _id séquentiel. À titre d'exemple, en utilisant les données suivantes:

[ 
    {_id: 1, value: 'Example One' }, 
    {_id: 2, value: 'Example Two' }, 
    {_id: 3, value: 'Example Three' }, 
    {_id: 4, value: 'Example Four' }, 
    {_id: 5, value: 'Example Five' }, 
    {_id: 6, value: 'Example Six' }, 
    ... 
] 

si je recherche pour « Four » en ES, je reviens le document _id de 4, car il est séquentiel que je peux créer une requête mongo pour tirer une fourchette comprise entre id - 2 et id + 2, dans ce cas 2 - 6. Cela fonctionne bien, tant que je ne supprime jamais de documents. Lorsque je supprime un document, je dois réindexer toute la série pour éliminer l'écart. Je cherche un moyen d'atteindre les mêmes résultats, mais aussi de pouvoir supprimer des documents sans devoir mettre à jour tous les documents.

Je suis ouvert à l'utilisation d'autres technologies pour y parvenir, je ne suis pas nécessairement lié à mongodb.

Répondre

0

Ce problème n'a rien à voir avec MongoDB en particulier et n'est pas différent de l'utilisation d'une base de données différente ici (par exemple un SGBDR). Vous devrez faire une boucle pour les identifiants de document plus petits/plus grands que l'identifiant actuel et trouver les deux premiers correspondants. Oui, cela signifie que vous devez effectuer plusieurs requêtes. La seule autre option consiste à implémenter une liste chaînée au-dessus de MongoDB où vous stockez des pointeurs vers le nœud voisin droit et gauche. Et oui, en cas de suppression, vous devez ajuster les pointeurs (algorithmes de base de la structure de données ....). L'inconvénient est: vous aurez besoin de plusieurs opérations pour effectuer les changements. Étant donné que MongoDB n'est pas une transaction, vous risquez de rencontrer des pointeurs incohérents précédent/suivant ... c'est pourquoi MongoDB est complètement nul ici.

+0

Il existe d'autres moyens de résoudre le problème lors de l'utilisation de SGBDR. En utilisant SQL Server par exemple, je pourrais utiliser un CTE avec ROW_NUMBER. Je peux être en mesure d'obtenir ce que je cherche en utilisant une fonction de réduction de la carte. Je vais devoir regarder ça. –

1

je peux obtenir les résultats souhaités en utilisant quelque chose comme ce qui suit:

collection.find({_id: { $gte: matchedId } }).limit(3); 
collection.find({_id: { $lt: matchedId } }).sort({$natural: -1}).limit(2); 

pas aussi bien que l'utilisation d'une gamme explicite, mais pas besoin de quoi que ce soit sur recalcule suppression de documents.

Oui, je connais le limitations of natural order, et ce n'est pas un problème pour mon cas d'utilisation particulier.

+0

Une mise en garde sur l'ordre naturel: sauf si vous avez une collection plafonnée, l'ordre naturel au fil du temps ne correspondra pas aux documents "précédent/suivant" comme vous l'attendez. En particulier, la suppression et le déplacement de documents créeront des espaces dans l'espace de données disponible où les documents peuvent être insérés ou déplacés. Si vous attendez un certain ordre (tel que l'ordre d'insertion), vous devez utiliser un tri indexé explicite() à la place. Dans votre exemple, vous voudriez trier sur le champ '_id'. – Stennie

Questions connexes