Buscando valor de cualquier campo en MongoDB sin nombrarlo explícitamente

Busqué en la documentación de MongoDB y busqué en Google esta pregunta, pero no pude encontrar una respuesta adecuada. Entonces, esto es lo que estoy buscando. Supongamos que tengo una colección con elementos como este:

{ "foo" : "bar", "test" : "test", "key" : "value", } 

Lo que me gustaría lograr es encontrar un elemento buscando en todos los campos (tal vez, excepto para muchos ;-)). En otras palabras: dada una consulta, NO sé en qué campo se debe encontrar la consulta.

En mi pensamiento algo como esto

 db.things.find({_ANY_ : "bar"}) 

me daría el elemento de ejemplo.

Gracias por tu ayuda.

Esto no es posible sin la inspección individual de documentos en la aplicación o mediante la ejecución del código del lado del servidor. Considere cambiar su esquema a:

 {params:[{field:"foo", value:"bar"}, {field:"test", value:"test"}, {field:"key", value:"value"}]} 

Obviamente, esto tiene algunos inconvenientes (rendimiento y esquema poluted en su mayoría), pero permitirá lo que necesita a través de:

 db.things.find({'params.value':"bar"}) 

Para realizar una búsqueda de texto en todos los campos, primero debe crear un índice de texto en todos los campos.

como indica la documentación de mongodb , “Para permitir la búsqueda de texto en todos los campos con contenido de cadena, use el especificador de comodín ($ **) para indexar todos los campos que contienen contenido de cadena.”

si está trabajando dentro de mongo shell (que ejecuta desde la línea de comando llamando ‘mongo’), puede hacerlo con este comando, donde ‘colección’ es el nombre de la colección en el archivo de contexto que desea utilizar.

db.collection.createIndex({ "$**": "text" },{ name: "TextIndex" })

el segundo objeto, es decir, {name:"TextIndex"} , es opcional … en realidad no es necesario darle un nombre al índice, ya que solo puede haber un índice de texto por colección (a la vez … puede soltar índices y crear nuevos si lo desea).

una vez que haya creado un índice de texto en todos los campos, puede hacer una búsqueda de texto simple con el siguiente objeto de consulta: { $text : { $search: } }

entonces, si estás escribiendo una función de JavaScript, puedes hacer algo como:

var cursor = db.collection().find({ $text: { $search: } });

para obtener más información sobre las diversas formas de controlar la búsqueda, consulte la documentación de mongodb sobre búsqueda de texto aquí.

Esta respuesta a una pregunta similar tiene su solución, que repetiré aquí para completarla. Puede usar el operador $where para ejecutar JavaScript arbitrario en el (los) servidor (es) MongoDB, con la advertencia de que esto será mucho más lento que casi cualquier otro tipo de consulta. Para su ejemplo, sería:

 db.things.find({$where: function() { for (var key in this) { if (this[key] === "bar") { return true; } return false; } }}); 

Lamentablemente, ninguna de las respuestas anteriores aborda el hecho de que mongo puede contener valores nesteds en matrices u objetos nesteds.

ESTA ES LA PREGUNTA CORRECTA:

 {$where: function() { var deepIterate = function (obj, value) { for (var field in obj) { if (obj[field] == value){ return true; } var found = false; if ( typeof obj[field] === 'object') { found = deepIterate(obj[field], value) if (found) { return true; } } } return false; }; return deepIterate(this, "573c79aef4ef4b9a9523028f") }} 

Como la invocación de typeof en array u objeto nested devolverá ‘object’, esto significa que la consulta iterará en todos los elementos nesteds y repetirá todo el tiempo hasta que se encuentre la clave con valor.

Puede verificar las respuestas anteriores con un valor nested y los resultados estarán lejos de ser deseados.

La encadenación de todo el objeto es mucho menos efectiva ya que tiene que iterar a través de todos los sectores de memoria uno por uno tratando de hacerlos coincidir. Y crea una copia del objeto como una cadena en la memoria RAM (ambas ineficientes ya que la consulta usa más ram y slow ya que el contexto de la función ya tiene un objeto cargado)

Puedes hacerlo con una función recursiva:

 var recursiveSearch = function(query) { db.test_insert.find().forEach(function(items) { var i = 0; var recursiveFunc = function(itemsArray, itemKey) { var itemValue = itemsArray[itemKey]; if(itemValue === query) { printjson(items); } if(typeof itemValue === "object") { Object.keys(itemValue).forEach(function(itemValueKey) { recursiveFunc(itemValue, itemValueKey); }); } }; Object.keys(items).forEach(function(item){ recursiveFunc(items, item); }); }); }; recursiveSearch('your string'); 

Para realizar una búsqueda de texto, debe crear índices de texto para su colección. Para obtener más información, consulte la documentación de mongo: índices de texto

Usar $ donde es lo mismo que hacer una exploración de tabla completa y no puede usar los índices. Tampoco pude hacerlo funcionar, sin embargo, encontré que funcionó (también es equivalente a una exploración de tabla completa):

 db.collection.find().forEach(function(doc){ for (var key in doc) { if ( /needle/.test(doc[key]) ) printjson(doc); } }); 

donde /needle/ es una expresión regular para encontrar en el valor de doc[key]

 { "foo" : "bar", "test" : "test", "key" : "value", } db.collection_name.find({'foo':"bar"}) 
Intereting Posts