sql >> Base de Datos >  >> NoSQL >> MongoDB

Cómo encontrar documentos con exactamente las mismas entradas de matriz que en una consulta

Hay varios "casos muy útiles" aquí en los que, de hecho, tratar de crear un "hash único" sobre el contenido de la matriz es en realidad "obstaculizar" la gran cantidad de problemas que se pueden abordar fácilmente.

Encontrar algo común a "yo"

Si, por ejemplo, toma "usuario 1" de la muestra proporcionada y considera que ya tiene esos datos cargados y desea encontrar "aquellos en común conmigo" por los "itemsIds" coincidentes de lo que tiene el objeto de usuario actual, entonces hay son dos enfoques de consulta simples:

  1. Encuentra "exactamente" lo mismo: Es donde desea inspeccionar los datos de otros usuarios para ver aquellos usuarios que tienen los mismos intereses "exactos". Este es un uso simple y "desordenado" del $all operador de consulta:

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

    Que va a devolver "usuario 3" ya que son los que tienen "ambas" entradas comunes de "itemsIds". El orden no es importante aquí, ya que siempre es una coincidencia en cualquier orden, siempre que ambos estén allí. Esta es otra forma de $and como argumentos de consulta.

  2. Encontrar "similares" en común conmigo": Que básicamente es preguntar "¿tienes algo que sea igual?" . Para eso puedes usar el $in operador de consulta Coincidirá si se cumple "alguna" de las condiciones especificadas:

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

    En este caso, "tanto" el "usuario 2" como el "usuario 3" van a coincidir, ya que "al menos" comparten "una" de las condiciones especificadas y eso significa que tienen "algo en común" con los datos de origen de la consulta.

    De hecho, esta es otra forma de $or operador de consulta, y al igual que antes, es mucho más simple y conciso escribir de esta manera dadas las condiciones que se aplicarán.

Encontrar "cosas" comunes

También hay casos en los que es posible que desee encontrar cosas "en común" sin tener un "usuario" base desde el que empezar. Entonces, ¿cómo saber que el "usuario 1" y el "usuario 2" comparten los mismos "itemIds" o, de hecho, que varios de los usuarios pueden compartir el mismo valor de "itemIds" individualmente, pero quiénes son?

  1. Obtenga las coincidencias exactas: Por supuesto, es donde observa los valores de "itemsIds" y $group ellos juntos. En general, el "orden es importante" aquí, por lo que de manera óptima los tiene "pedidos por adelantado" y siempre de manera consistente para que esto sea tan simple como:

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

    Y eso es todo lo que realmente hay, siempre que la orden ya esté allí. De lo contrario, puede hacer un formulario un poco más largo para hacer el "orden", pero lo mismo podría decirse de generar un "hash":

    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" }
        }}
    ])
    

    No tiene un rendimiento "súper", pero explica por qué siempre se mantiene ordenado al agregar entradas de matriz. Que es un proceso muy simple.

  2. Común "usuario" a "elementos": Que es otro proceso simple que se abstrae de arriba con "desglosar" la matriz en $unwind , y luego básicamente agrupando de nuevo:

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

    Y nuevamente, solo un agregador de agrupación simple de $addToSet hace el trabajo y recopila los valores de "identificación de usuario distintos" para cada valor de "identificación de elementos".

Todas estas son soluciones básicas, y podría continuar con "establecer intersecciones" y otras cosas, pero esta es la "instrucción".

No intente calcular un "hash", MongoDB tiene un buen "arsenal" para hacer coincidir las entradas de todos modos. Úsalo y "abusa de él" también, hasta que se rompa. Entonces esfuérzate más.