필드에 문자열이 포함되어 있는지 확인


453

필드 값에 특정 문자열이 포함되어 있는지 확인할 수있는 연산자를 찾고 있습니다.

다음과 같은 것 :

db.users.findOne({$contains:{"username":"son"}})

가능합니까?

답변:


692

다음 코드를 사용하여 수행 할 수 있습니다.

db.users.findOne({"username" : {$regex : ".*son.*"}});

16
이렇게하면 인덱스를 효율적으로 사용할 수 없으며 모든 값이 일치 하는지 스캔됩니다. 정규 표현식
Stennie

7
@Stennie, 인덱스를 효율적으로 사용하고 부분 문자열을 찾는 것이 무엇을 제안합니까?
Blue Sky

4
@Vish : 일반적인 유스 케이스가 필드의 자유 텍스트 검색이고 많은 문서가있는 경우 더 효율적인 쿼리를 위해 텍스트를 토큰 화합니다. 간단한 전체 텍스트 검색에 다중 키 를 사용 하거나 별도의 컬렉션으로 거꾸로 된 색인 을 구축 할 수 있습니다. 자주 검색하지 않거나 작은 문서 모음의 경우 전체 색인을 스캔하면 성능이 좋지는 않지만 적절한 성능을 발휘할 수 있습니다.
Stennie

98
이것은 약간 과잉 아닌가요? 당신이 원하는 것은 db.users.findOne({"username" : {$regex : "son"}});
JamieJag

3
Mongo 2.6에서 전체 텍스트 검색을 확인하고 싶을 수도 있습니다
wprl

179

Mongo 쉘이 정규식을 지원하므로 완전히 가능합니다.

db.users.findOne({"username" : /.*son.*/});

쿼리에서 대소 문자를 구분하지 않으려면 아래에 표시된 것처럼 "i"옵션을 사용할 수 있습니다.

db.users.findOne({"username" : /.*son.*/i});

참조 : http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions


1
검색을위한 정규식 사용법을 보여주는 코드 스 니펫을 포함하십시오. 답변은 단순한 링크보다 더 많은 정보를 포함해야합니다 ...
maerics

1
선택한 답변이 저에게 효과가 없었지만이 답변은 도커 실행 명령을 통해 몽고 쿼리를 실행하고 있습니다.
Arthur Weborg

5
선택한 답변의 의견과 마찬가지로 내가 db.users.findOne({"username" : /.*son.*/});과도하게 사용할 수 있다고 생각 하고 정규 표현식은 간단 할 수 있습니다./son/
Arthur Weborg

2
$ regex를 사용하는 것보다 더 간결한 방법
Lionet Chen

4
편집이 단지 사용에{ username: /son/ }
Wyck

150

https://docs.mongodb.com/manual/reference/sql-comparison/

http://php.net/manual/en/mongo.sqltomongo.php

MySQL

SELECT * FROM users WHERE username LIKE "%Son%"

몽고 DB

db.users.find({username:/Son/})

8
귀하의 MongoDB 답변이 좋습니다. 관련없는 MySQL 조언을 제거하려면 질문을 편집하십시오.
maerics

31
모든 쿼리를 제거하거나 변경 하시겠습니까? 알려진 대부분의 사람들 SQL, 그것은 MongoDB를 이해하는 데 도움이됩니다
Zheng Kai

4
@ZhengKai :이 웹 사이트에서는 일반적으로 태그가 지정된 특정 기술 만 사용하여 질문에 직접 대답해야합니다.
maerics

98
@maerics 개인적으로 Zheng이 MySQL을 포함시키는 것이 매우 중요한 것으로 나타났습니다.
Mike Bartlett

50
또한 SQL 참조와 관련이 있다는 것을 알았습니다.
vikingsteve

69

버전 2.4부터는 필드에 텍스트 인덱스 를 만들어 쿼리에 $ text 연산자 를 검색하고 사용할 수 있습니다 .

먼저 색인을 작성하십시오.

db.users.createIndex( { "username": "text" } )

그런 다음 검색하십시오.

db.users.find( { $text: { $search: "son" } } )

벤치 마크 (~ 150K 문서) :

  • 정규식 (다른 답변) => 5.6-6.9 초
  • 텍스트 검색 => .164-.201 초

노트:

  • 컬렉션은 하나의 텍스트 인덱스 만 가질 수 있습니다. 검색 할 경우 와일드 카드 텍스트 인덱스를 사용할 수 있는 이 같은 문자열 필드 : db.collection.createIndex( { "$**": "text" } ).
  • 텍스트 인덱스는 클 수 있습니다. 여기에는 삽입 된 각 문서에 대한 각 색인 필드에 고유 한 사후 스테 밍 단어에 대한 하나의 색인 항목이 포함됩니다.
  • 텍스트 인덱스는 일반 인덱스보다 빌드하는 데 시간이 더 걸립니다.
  • 텍스트 색인은 문서에서 단어의 근접성에 대한 문구 나 정보를 저장하지 않습니다. 결과적으로 전체 컬렉션이 RAM에 들어가면 구문 쿼리가 훨씬 더 효과적으로 실행됩니다.

14
아니요, 사실 텍스트 연산자는 "포함"을 실행할 수 없으므로 정확한 단어 일치 만 반환합니다. 현재 3.0부터 유일하게 사용할 수있는 옵션은 regex를 사용하는 것입니다. 즉 db.users.find ({username : / son / i} ) "son"(대소 문자 구분)을 포함하는 모든 사용자를 조회합니다.
comeGetSome

3
컬렉션에 문서를 추가하거나 제거 할 때 색인을 다시 작성해야합니까?
Jake Wilson

질문의 제목은 "포함한다"고 말합니다. 질문에는 전문 검색이 적용되지 않습니다.
Donato

29

이것이 검색 엔진의 첫 번째 히트 중 하나이며 위의 어느 것도 MongoDB 3.x에서 작동하지 않는 것이므로 다음은 작동하는 정규식 검색입니다.

db.users.find( { 'name' : { '$regex' : yourvalue, '$options' : 'i' } } )

별도의 색인을 만들 필요가 없습니다.


1
정규식을 위생 처리해야합니다.
sean

16

Python을 통해 MongoDB를 연결하는 경우 수행해야 할 작업은 다음과 같습니다.

db.users.find({"username": {'$regex' : '.*' + 'Son' + '.*'}})

'Son'대신 변수 이름을 사용하여 문자열 연결을 사용할 수도 있습니다.


es2015에 당신은 {$ 정규식 : 역 따옴표를 사용할 수 있습니다 .*${value}.*}
마이클 길드

16

이 작업을 수행하는 가장 간단한 방법

쿼리가 대소 문자를 구분하도록하려면

db.getCollection("users").find({'username':/Son/})

쿼리를 대소 문자를 구분하지 않으려면

db.getCollection("users").find({'username':/Son/i})

1
정규식으로 변수를 사용하는 방법 ??
Hisham 2018 년

4

대소 문자를 구분하지 않는 사용 색인 i 옵션에 대한 이상적인 답변

db.users.findOne({"username" : new RegExp(search_value, 'i') });

정규식을 위생 처리해야합니다.
sean


1

RegExp 일치에서 HTML 태그를 무시하는 방법 :

var text = '<p>The <b>tiger</b> (<i>Panthera tigris</i>) is the largest <a href="https://stackoverflow.com/wiki/Felidae" title="Felidae">cat</a> <a href="https://stackoverflow.com/wiki/Species" title="Species">species</a>, most recognizable for its pattern of dark vertical stripes on reddish-orange fur with a lighter underside. The species is classified in the genus <i><a href="https://stackoverflow.com/wiki/Panthera" title="Panthera">Panthera</a></i> with the <a href="https://stackoverflow.com/wiki/Lion" title="Lion">lion</a>, <a href="https://stackoverflow.com/wiki/Leopard" title="Leopard">leopard</a>, <a href="https://stackoverflow.com/wiki/Jaguar" title="Jaguar">jaguar</a>, and <a href="https://stackoverflow.com/wiki/Snow_leopard" title="Snow leopard">snow leopard</a>. It is an <a href="https://stackoverflow.com/wiki/Apex_predator" title="Apex predator">apex predator</a>, primarily preying on <a href="https://stackoverflow.com/wiki/Ungulate" title="Ungulate">ungulates</a> such as <a href="https://stackoverflow.com/wiki/Deer" title="Deer">deer</a> and <a href="https://stackoverflow.com/wiki/Bovid" class="mw-redirect" title="Bovid">bovids</a>.</p>';
var searchString = 'largest cat species';

var rx = '';
searchString.split(' ').forEach(e => {
  rx += '('+e+')((?:\\s*(?:<\/?\\w[^<>]*>)?\\s*)*)';
});

rx = new RegExp(rx, 'igm');

console.log(text.match(rx));

이것은 아마도 MongoDB 집계 필터로 전환하기가 매우 쉽습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.