명시 적으로 이름을 지정하지 않고 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
'programing' 카테고리의 다른 글
목록 상자를 목록에 바인딩 (0) | 2021.01.14 |
---|---|
R로 SPSS 파일 읽기 (0) | 2021.01.14 |
stringio 객체를 어떻게 지우나요? (0) | 2021.01.14 |
while 루프 대신 For 루프 (0) | 2021.01.14 |
zip 파일에 포함 된 파일 목록 가져 오기 (0) | 2021.01.14 |