ตรวจสอบว่าเขตข้อมูลมีสตริง


454

ฉันกำลังมองหาผู้ดำเนินการซึ่งช่วยให้ฉันตรวจสอบว่าค่าของเขตข้อมูลมีสตริงที่แน่นอน

สิ่งที่ต้องการ:

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

เป็นไปได้ไหม

คำตอบ:


693

คุณสามารถทำได้ด้วยรหัสต่อไปนี้

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

16
โปรดทราบว่านี่จะไม่ใช้ดัชนีอย่างมีประสิทธิภาพและส่งผลให้ค่าทั้งหมดถูกสแกนเพื่อจับคู่ ดูหมายเหตุเกี่ยวกับนิพจน์ทั่วไป
Stennie

7
@Stennie แล้วคุณแนะนำให้ใช้ดัชนีอย่างมีประสิทธิภาพและค้นหาสตริงย่อยอย่างไร
Blue Sky

4
@Vish: หากกรณีการใช้งานทั่วไปของคุณคือการค้นหาข้อความในฟิลด์และคุณมีเอกสารจำนวนมากฉันจะโทเค็นข้อความสำหรับการสืบค้นที่มีประสิทธิภาพมากขึ้น คุณสามารถใช้multikeysสำหรับการค้นหาข้อความแบบเต็มหรืออาจสร้างดัชนีแบบกลับด้านเป็นชุดสะสมแยกต่างหาก สำหรับการค้นหาไม่บ่อยนักหรือเอกสารจำนวนเล็กน้อยการสแกนดัชนีแบบเต็มอาจเป็นที่ยอมรับ (แม้ว่าจะไม่เหมาะสม)
Stennie

98
นี่เป็นบิตของการทำเกินจริงหรือไม่? สิ่งที่คุณต้องการคือ db.users.findOne({"username" : {$regex : "son"}});
JamieJag

3
อาจต้องการตรวจสอบการค้นหาข้อความแบบเต็มใน Mongo 2.6
wprl

179

ในฐานะที่เป็น Mongo shell สนับสนุน regex เป็นไปได้อย่างสมบูรณ์

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
คำตอบที่เลือกไม่ได้ผลสำหรับฉัน แต่อันนี้ทำ (ฉันกำลังประมวลผลคำสั่ง mongo ผ่านคำสั่ง execer docker) ฉันคิดว่าคำตอบนี้ควรเป็นคำตอบที่เลือกเพราะดูเหมือนจะมีประโยชน์มากกว่า
Arthur Weborg

5
เช่นความคิดเห็นในคำตอบที่เลือกฉันเชื่อว่าdb.users.findOne({"username" : /.*son.*/});อาจ overkill และ regex ได้ง่าย/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%"

MongoDB

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

8
คำตอบ MongoDB ของคุณดี พิจารณาแก้ไขคำถามของคุณเพื่อลบคำแนะนำ MySQL ที่ไม่เกี่ยวข้องออก
maerics

31
ลบข้อความค้นหาทั้งหมดหรือเปลี่ยนแปลงหรือไม่ poeple ที่รู้จักกันมากที่สุด SQL จะเป็นประโยชน์สำหรับการทำความเข้าใจ MongoDB
เจิ้งไก่

4
@ZhengKai: บนเว็บไซต์นี้คุณควรตอบคำถามโดยตรงโดยใช้เฉพาะเทคโนโลยีที่ติดแท็กและร้องขอ
maerics

98
@ maerics เป็นการส่วนตัวฉันพบว่าการรวม MySQL ของเจิ้งเหอเป็นประโยชน์อย่างมากเพราะมันเป็นจุดอ้างอิง
Mike Bartlett

50
ฉันยังพบการอ้างอิง SQL ที่เกี่ยวข้องฉันคิดว่าควรจะอยู่
vikingsteve

69

ในเวอร์ชัน 2.4 คุณสามารถสร้างดัชนีข้อความบนฟิลด์เพื่อค้นหาและใช้ตัวดำเนินการ$ textสำหรับการสืบค้น

ขั้นแรกสร้างดัชนี:

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

จากนั้นเพื่อค้นหา:

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

มาตรฐาน (เอกสารประมาณ 150K):

  • Regex (คำตอบอื่น ๆ ) => 5.6-6.9 วินาที
  • การค้นหาข้อความ => .164-.201 วินาที

หมายเหตุ:

  • คอลเล็กชันสามารถมีดัชนีข้อความได้เพียงดัชนีเดียว คุณสามารถใช้ดัชนีข้อความสัญลักษณ์แทนถ้าคุณต้องการค้นหาใด ๆdb.collection.createIndex( { "$**": "text" } )ฟิลด์สตริงเช่นนี้
  • ดัชนีข้อความอาจมีขนาดใหญ่ มันมีรายการดัชนีหนึ่งรายการสำหรับคำที่โพสต์ Stemmed ที่ไม่ซ้ำกันในแต่ละฟิลด์ที่มีการทำดัชนีสำหรับแต่ละเอกสารที่แทรก
  • ดัชนีข้อความจะใช้เวลาในการสร้างนานกว่าดัชนีปกติ
  • ดัชนีข้อความไม่ได้จัดเก็บวลีหรือข้อมูลเกี่ยวกับความใกล้เคียงของคำในเอกสาร ดังนั้นการค้นหาวลีจะทำงานได้อย่างมีประสิทธิภาพมากขึ้นเมื่อการรวบรวมทั้งหมดเหมาะกับ RAM

14
ไม่ผู้ประกอบการข้อความ infact ไม่อนุญาตให้ดำเนินการ "มี" ดังนั้นมันจะกลับเฉพาะการจับคู่คำที่แน่นอนตัวเลือกเดียวในปัจจุบันเป็น 3.0 คือการใช้ regex เช่น db.users.find ({ชื่อผู้ใช้: / son / i} ) สิ่งนี้ค้นหาผู้ใช้ทุกคนที่มีคำว่า "son" (case-
insenstive

3
คุณต้องทำดัชนีใหม่เมื่อคุณเพิ่มหรือลบเอกสารไปยัง / จากการรวบรวมหรือไม่?
Jake Wilson

ชื่อของคำถามที่ระบุว่า "บรรจุ" การค้นหาข้อความแบบเต็มไม่สามารถใช้ได้กับคำถาม
Donato

29

เนื่องจากนี่เป็นหนึ่งในเพลงฮิตอันดับแรกในเครื่องมือค้นหาและดูเหมือนว่าจะไม่มีการทำงานใด ๆ กับ MongoDB 3.x นี่คือการค้นหา regex หนึ่งรายการที่ใช้งานได้:

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

ไม่จำเป็นต้องสร้างและจัดทำดัชนีเพิ่มเติมหรือเหมือนกัน


1
Regexes ต้องผ่านการฆ่าเชื้อ
ฌอน

16

นี่คือสิ่งที่คุณต้องทำถ้าคุณเชื่อมต่อ MongoDB ผ่าน Python

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

คุณอาจใช้ชื่อตัวแปรแทน 'Son' และดังนั้นการต่อสตริง


ใน es2015 คุณสามารถใช้ backticks {$ regex: .*${value}.*}
Michael Guild

16

วิธีที่ง่ายที่สุดในการทำภารกิจนี้ให้สำเร็จ

หากคุณต้องการให้แบบสอบถามเป็นแบบตรงตัวพิมพ์

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

ถ้าคุณต้องการให้แบบสอบถามคำนึงถึงขนาดตัวพิมพ์

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

1
วิธีการใช้ตัวแปรด้วย regex?
Hisham

4

คำตอบที่เหมาะดัชนีการใช้ ฉันเป็นตัวเลือกสำหรับกรณีตาย

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

Regexes ต้องผ่านการฆ่าเชื้อ
ฌอน

2

สิ่งนี้ควรทำผลงาน

db.users.find({ username: { $in: [ /son/i ] } });

iเป็นเพียงเพื่อป้องกันไม่ให้มีข้อ จำกัด ของการจับคู่กรณีเดียวของตัวอักษร

คุณสามารถตรวจสอบเอกสาร $ regex ในเอกสาร MongoDB นี่คือลิงค์: https://docs.mongodb.com/manual/reference/operator/query/regex/


1

วิธีละเว้นแท็ก HTML ในการจับคู่ RegExp:

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.