MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Comment trouver des documents avec exactement les mêmes entrées de tableau que dans une requête

Il existe plusieurs "cas très utiles" ici où, en fait, essayer de créer un "hachage unique" sur le contenu du tableau "gêne" la myriade de problèmes qui peuvent être facilement résolus.

Trouver ce qui est commun à "moi"

Si vous prenez par exemple "l'utilisateur 1" de l'exemple fourni, et considérez que vous avez déjà chargé ces données et que vous voulez trouver "ceux en commun avec moi" par les "itemsIds" correspondants à partir de ce que l'objet utilisateur actuel a, alors là deux approches de requête simples :

  1. Trouvez "exactement" la même : C'est là que vous souhaitez inspecter les données d'autres utilisateurs pour voir les utilisateurs qui ont les mêmes intérêts "exacts". Il s'agit d'une utilisation simple et "non ordonnée" du $all opérateur de requête :

    db.collection.find({ 
        "itemsIds": { "$all": [399957190, 366369952] },
        "userId": { "$ne": 1 }
    })
    

    Ce qui va renvoyer "l'utilisateur 3" car ce sont eux qui ont "les deux" entrées "itemsIds" communes. L'ordre n'est pas important ici car c'est toujours un match dans n'importe quel ordre, tant qu'ils sont tous les deux là. Ceci est une autre forme de $and comme arguments de requête.

  2. Trouver "semblable" en commun avec moi : Ce qui revient essentiellement à demander "avez-vous quelque chose qui est pareil ?" . Pour cela, vous pouvez utiliser le $in opérateur de requête. Il correspondra si "l'une ou l'autre" des conditions spécifiées est remplie :

    db.collection.find({ 
        "itemsIds": { "$in": [399957190, 366369952] },
        "userId": { "$ne": 1 }
    })
    

    Dans ce cas, "les deux" "utilisateur 2" et "utilisateur 3" vont correspondre, car ils partagent "au moins" "une" des conditions spécifiées et cela signifie qu'ils ont "quelque chose en commun" avec les données source de la requête.

    C'est en fait une autre forme du $or opérateur de requête, et comme avant c'est beaucoup plus simple et concis d'écrire de cette façon compte tenu des conditions à appliquer.

Trouver des "choses" courantes

Il y a aussi des cas où vous voudrez peut-être trouver des choses "en commun" sans avoir un "utilisateur" de base pour commencer. Alors, comment savoir que "l'utilisateur 1" et "l'utilisateur 2" partagent les mêmes "itemIds", ou en fait que plusieurs utilisateurs peuvent partager la même valeur "itemIds" individuellement, mais qui sont-ils ?

  1. Obtenir les correspondances exactes : Est bien sûr où vous regardez les valeurs "itemsIds" et $group eux autres ensemble. Généralement, la "commande est importante" ici, donc de manière optimale, vous les avez "pré-commandés" et toujours pour que cela soit aussi simple que :

    db.collection.aggregate([
        { "$group": {
            "_id": "$itemsIds",
            "common": { "$push": "$userId" }
        }}
    ])
    

    Et c'est tout ce qu'il y a vraiment à faire, tant que la commande est déjà là. Si ce n'est pas le cas, vous pouvez créer un formulaire légèrement plus long pour effectuer la "commande", mais on pourrait en dire autant de la génération d'un "hachage":

    db.collection.aggregate([
        { "$unwind": "$itemsIds" },
        { "$sort": { "_id": 1, "itemsIds": 1 } },
        { "$group": {
            "_id": "$_id",
            "userId": { "$first": "$userId" },
            "itemsIds": { "$push": "$itemsIds" }
        }},
        { "$group": {
            "_id": "$itemsIds",
            "common": { "$push": "$userId" }
        }}
    ])
    

    Pas "super" performant, mais cela explique pourquoi vous gardez toujours l'ordre lors de l'ajout d'entrées de tableau. Ce qui est un processus très simple.

  2. "Utilisateur" commun aux "éléments" : Qui est un autre processus simple abstrait ci-dessus avec "décomposer" le tableau sous $unwind , puis en regroupant :

    db.collection.aggregate([
        { "$unwind": "$itemsIds" },
        { "$group": {
            "_id": "$itemsIds",
            "users": { "$addToSet": "$userId" }
        }}
    ])
    

    Et encore une fois, juste un simple agrégateur de regroupement de $addToSet fait le travail et collecte les valeurs "userId distinctes" pour chaque valeur "itemsIds".

Ce sont toutes des solutions de base, et je pourrais continuer avec les "intersections définies" et ainsi de suite, mais c'est "l'amorce".

N'essayez pas de calculer un "hachage", MongoDB a un bon "arsenal" pour faire correspondre les entrées de toute façon. Utilisez-le et "abusez-en" ainsi, jusqu'à ce qu'il casse. Alors essayez plus fort.