【问题标题】:How to perform "like" query with full text search in mongodb?如何在 mongodb 中使用全文搜索执行“like”查询?
【发布时间】:2017-01-09 06:44:22
【问题描述】:

我知道mongo目前不支持$regex or like operation全文搜索。它只匹配文本或短语。但我需要对索引字段执行类似查询搜索。因此,我需要有关选择多个搜索框架或解决此问题的任何其他解决方法的帮助。

我有嵌套的文档结构。例如:

{
"name": "John",
"phones": [{
    "phone_number": "1234",
    "is_primary": true
}, {
    "phone_number": "5678",
    "is_primary": false
}]
}

我曾尝试使用 Apache Solr,但我发现它不能很好地支持嵌套文档。它使结构变平并为字段编制索引,但是当我尝试执行上面讨论的类似查询时,它不起作用。

我正在使用 scala、play 和 mongodb。我现在无法更改嵌套文档结构。我可以与 mongodb 集成以开发强大的搜索框架的合适搜索平台有哪些?我该如何处理这个问题?在这种情况下,最好的方法是什么?

【问题讨论】:

  • 您需要创建text index才能在mongodb中获得全文搜索支持
  • @ShaishabRoy 我已经创建了文本索引。我需要的是文本搜索中的 $regex 搜索。
  • 执行文本搜索不需要使用$regex,你应该使用$text$search。可以看到我的答案@oblivion

标签: mongodb scala solr full-text-search


【解决方案1】:

要执行类似全文搜索,您可以创建text index 然后使用。 more about text index

创建文本索引的语法

db.colectionName.createIndex( { fieldName: "text" } );

这里显示的是单个字段,您也可以使用多个字段创建。但请记住

一个集合最多可以有一个文本索引。

然后您可以使用$text$search 进行搜索

var searchText= 'some text to search';
db.collectionName.find({ $text: { $search: searchText} });

但是序列匹配或者模式匹配不需要创建text index可以使用$regex

var searchName ='som';
db.collectionName.find({"name":{ $regex: searchName, $options: 'i' }})

对于上面带有$regex 的查询,将部分匹配。例如在你的数据库中name:'some text to search' 所以如果searchName 值像some,som,ome,rex 这样可以返回数据...

为了更好的性能可以为name字段创建普通索引

【讨论】:

  • 我需要使用文本搜索执行类似查询。例如: db.colectionName.createIndex( { fieldName: "text" } ); db.colectionName.insert( {"text":"要搜索的东西" } ); db.collectionName.find({ $text: { $search: "som"} });如您所见,我的意思是我需要带有文本搜索的 $regex 功能。
  • $regex 用于精确序列匹配或模式匹配,不像text search
  • 我知道,我正在寻找可以使用实际文本的子字符串进行搜索的部分文本搜索。
  • 那么使用text index有什么问题?
  • 根据您的第一条评论,您可能会错过对text index 的了解。您使用"text":"some thing to search"添加无效的新记录您应该使用.insert( {"fieldName":"some thing to search",为此fieldName您应该创建text index,然后使用.find({ $text: { $search: "som"} }),这将从fieldName值中找到
【解决方案2】:

您可以在 SOLR 中执行此操作,但您需要提前定义您想要执行的查询类型,并以创造性的方式展平索引,以便查询和检索您需要的内容。您可以使用多值字段来存储多个值。如果您的客户端需要实例化它,您可以将整个对象的 JSON 版本存储在文本字段中。

例如,您可以分别存储初级和次级:

phone_number_primary: 1234,...
phone_number_secondary: 5678,...
my_json_blob: {OBJECT HERE}

然后您可以分别检索和查询每个。如果您想同时搜索两者,您可以同时查询两者

 ( phone_number_primary:1234 OR phone_number_secondary:1234) 

或者您可以定义一个额外的字段来在您的架构中存储这两个数字:

 <copyField source="phone_number_*" dest="phone_number_all" />

然后搜索该字段。

【讨论】:

    猜你喜欢
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 2011-03-19
    相关资源
    最近更新 更多