programing

명시 적으로 이름을 지정하지 않고 MongoDB의 모든 필드 값 검색

kingscode 2021. 1. 14. 22:54
반응형

명시 적으로 이름을 지정하지 않고 MongoDB의 모든 필드 값 검색


MongoDB 문서를 살펴 보고이 질문을 검색했지만 실제로 적절한 답변을 찾을 수 없었습니다. 그래서 여기 제가 찾고있는 것이 있습니다. 다음과 같은 요소가있는 컬렉션이 있다고 가정합니다.

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

내가 달성하고 싶은 것은 모든 (유한히 많은 ;-) 필드를 제외하고는) 검색하여 요소를 찾는 것입니다. 즉, 쿼리가 주어지면 어떤 필드에서 쿼리를 찾아야하는지 알 수 없습니다.

이런 내 생각에

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

나에게 예제 요소를 줄 것입니다.

도와 주셔서 감사합니다.


모든 필드에서 텍스트 검색을 수행하려면 먼저 모든 필드에서 텍스트 인덱스를 만들어야합니다.

는 AS MongoDB의 설명서를 나타냅니다, "문자열의 내용을 포함하는 모든 필드 인덱스에 와일드 카드 지정자 ($ **)를 사용, 문자열 내용으로 모든 필드에 텍스트 검색을 허용합니다."

mongo 셸 ( 'mongo'를 호출하여 명령 줄에서 실행) 내에서 작업하는 경우 다음 명령을 사용하여 수행 할 수 있습니다. 여기서 'collection'은 사용하려는 db의 컬렉션 이름입니다.

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

두 번째 객체, 즉는 {name:"TextIndex"}선택 사항입니다 ... 실제로 색인에 이름을 지정할 필요가 없습니다. 컬렉션 당 하나의 텍스트 색인 만있을 수 있기 때문입니다 (한 번에 ... 색인을 삭제하고 새 색인을 만들 수 있습니다.) 네가 원한다면).

모든 필드에 텍스트 인덱스를 만든 후에는 다음 쿼리 개체를 사용하여 간단한 텍스트 검색을 수행 할 수 있습니다. { $text : { $search: <your string> } }

따라서 자바 스크립트 함수를 작성하는 경우 다음과 같이 할 수 있습니다.

var cursor = db.collection(<collection_name>).find({ $text: { $search: <your string> } });

검색을 제어하는 ​​다양한 방법에 대한 자세한 정보는 여기 에서 텍스트 검색에 대한 mongodb 문서를 참조 하십시오.


이는 앱 측에서 문서를 개별적으로 검사하거나 서버 측 코드 실행을 통해서는 불가능합니다. 스키마를 다음으로 변경하십시오.

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

이것은 분명히 몇 가지 단점이 있지만 (대부분 성능 및 오염 된 스키마) 필요한 것을 허용합니다.

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

이 답변 비슷한 질문에 내가 완성도 여기를 반복합니다 솔루션을 가지고 있습니다. $where연산자를 사용하여 MongoDB 서버에서 임의의 JavaScript를 실행할 수 있으며 , 이는 거의 모든 종류의 쿼리보다 훨씬 느리다는 점에 유의하십시오. 귀하의 예를 들면 다음과 같습니다.

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

슬프게도 이전 답변 중 어느 것도 mongo가 배열 또는 중첩 객체에 중첩 값을 포함 할 수 있다는 사실을 다루지 않습니다.

이것은 올바른 쿼리입니다.

{$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")
}}

배열 또는 중첩 된 객체에 대해 typeof를 호출하면 '객체'가 반환되므로 쿼리가 모든 중첩 된 요소에서 반복되고 값이있는 키를 찾을 때까지 모든 단계를 반복합니다.

중첩 된 값으로 이전 답변을 확인할 수 있으며 결과가 원하는 것과 멀어집니다.

전체 개체를 문자열 화하는 것은 모든 메모리 섹터를 일치시키기 위해 하나씩 반복해야하므로 성능이 훨씬 떨어집니다. 그리고 램 메모리에 문자열로 객체의 복사본을 생성합니다 (쿼리가 더 많은 램을 사용하기 때문에 비효율적이고 함수 컨텍스트에 이미로드 된 객체가 있기 때문에 느립니다).


재귀 함수로 할 수 있습니다.

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');

Using $where is the same as doing a full table scan and cannot use the indexes. I also could not get it working, however I did find this worked (it also does the equivalent of a full table scan) :

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

where /needle/ is a regular expression to find in the value of doc[key]


To do text search, you have to create text indexes for your collection. For more information, look at mongo documentation :indexes text


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

db.collection_name.find({'foo':"bar"})

ReferenceURL : https://stackoverflow.com/questions/6790819/searching-for-value-of-any-field-in-mongodb-without-explicitly-naming-it

반응형