【问题标题】:Find n words inside a Mongodb document在 Mongodb 文档中查找 n 个单词
【发布时间】:2015-01-28 05:27:23
【问题描述】:

我正在尝试创建一个查询来查找符合条件的文档集合,这是一个简单的搜索系统。问题是集合里面的资产是这样的:

{ 
 fristName: "foo",
 lastName: "bar",
 description: "mega foo",
},
{ 
 fristName: "Lorem",
 lastName: "Ipsum",
 description: "mega Lorem bla bla",
},

如果用户想要所有包含单词 bar 的资产,我应该显示示例的资产 1,这不是问题,但如果他输入 foo mega?,在这种情况下,我还需要显示资产 1,因为 foomega 存在于资产 1(两者)中,如果他只搜索 mega,输出是asset 1和2,如果他搜索mega ipsum,结果是asset 2。我不知道如何在mongoDb中编写这个查询。

【问题讨论】:

标签: mongodb


【解决方案1】:

Mongodb 2.6+ 内置了对使用 $text 运算符的文本搜索的支持。以下是它的使用方法。

  1. 在所需的可搜索字段上建立文本索引。注意:对于 MongoDB 2.6,一个集合只能有 1 个文本索引。

    在一个字段上创建文本索引

    db.test.ensureIndex({ 
        "field1" : "text"
     }, { name : "Field1TextIndex"});
    

    在两个字段上创建文本索引

    db.test.ensureIndex({ 
        "field1" : "text",
        "field2" : "text"
     }, { name : "Field12TextIndex"});
    

    为任何字符串字段创建文本索引

    db.test.ensureIndex({ 
        "$**" : "text" 
    }, { name : "AllTextIndex"});
    
  2. 使用 $text 运算符查询集合。

    这是$text的格式

    { $text: { $search: <string of keywords>, $language: <string> } }
    

示例代码

设置

use test;
var createPerson = function(f,l,d){
    return { firstName : f, lastName: l, description : d};
};
db.test.remove({});
db.test.insert(createPerson("Ben", "Dover", "Real Estate Agent"));
db.test.insert(createPerson("James", "Bond", "secret agent, ben's friend"));

为文档中的所有字符串字段创建文本索引。

db.test.ensureIndex({ "$**" : "text" }, { name : "AllTextIndex"});

查询所有字段的关键字

正在搜索ben

db.test.find({  
    $text : {
        $search : "ben"
    }
});

输出

{ "_id" : "...", "firstName" : "James", "lastName" : "Bond", "description" : "secret agent, ben's friend" }
{ "_id" : "...", "firstName" : "Ben", "lastName" : "Dover", "description" : "Real Estate Agent" }

搜索“ben”会返回两个文档,因为其中一个具有 Ben 作为 firstName,而另一个在 description 字段中具有 ben's

查询real friend 会产生相同的结果。

db.test.find({  
    $text : {
        $search : "real friend"
    }
});

更多信息在这里:

【讨论】:

    【解决方案2】:

    可能的解决方案是通过关键字进行搜索。我的意思是你必须为每个对象添加keywords 字段,例如:

    { 
     fristName: "foo",
     lastName: "bar",
     description: "mega foo",
     keywords: ["foo", "bar", "mega"]
    },
    { 
     fristName: "Lorem",
     lastName: "Ipsum",
     description: "mega Lorem bla bla",
     keywords: ["mega", "Lorem", "Ipsum", "bla"]
    },
    

    您必须将请求字符串拆分为关键字,例如

    "foo mega"
    

    会转换成

    ["foo", "mega"]
    

    然后您可以通过keywords 字段搜索对象。

    【讨论】:

    • 我不能修改资产结构,所以不能包含字段关键字
    • 在不考虑全文搜索的“词干”选项的情况下,我认为这是一个非常有效的选项。当然是常识性的方法。
    • @DomingoSL 但是处理数据的第一条规则是正确地对其进行规范化。所以这取决于你:)。
    • @DomingoSL 在此域中,“我无法修改”不是可接受的响应。和你的老板谈谈,他显然需要接受教育。送他去我的路。
    猜你喜欢
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 2021-07-25
    • 2016-08-25
    • 2016-04-18
    相关资源
    最近更新 更多