特别是在mongo中搜索

时间:2016-06-16 01:23:47

标签: mongodb search meteor reactjs

我有一个问题,假设我有一个名为contact的集合:

[
    {"firstName": "Adam", "lastName":"Peter", "email":"adam@peter.com"},
    {"firstName": "Adam", "lastName":"John", "email":"adam@john.com"},
    {"firstName": "Adam", "lastName":"Petkovic", "email":"adam@petkovic.com"}
]

我想要的是具体搜索,例如:我想搜索"Adam peter"然后我想得到第一个只有Adam和peter的结果。

我将meteor + mongo + react用于我的应用程序。

任何建议/建议都会受到高度赞赏。

感谢所有答案,但我可能需要更具体地询问以获得更合适的答案。

场景:

  • 我只有一个文本框来搜索所有字段。

所以:

  • 当我输入“Adam”时,我希望得到3个结果。但是当我进入“亚当彼得”时,我希望只有1个结果。

  • 当我输入“peter.com”时,它应该有1个结果

  • 当我输入“John”时,它应该有1个结果

  • 当我输入“Adam Pet”时,它应该有2个结果。

3 个答案:

答案 0 :(得分:1)

从回答here开始,下面的查询应该可以正常工作。

db.contacts.find( { firstName: /^Adam$/i, lastName: /^peter$/i });

答案 1 :(得分:0)

MongoDB中的查询区分大小写,如果要通过忽略大小写来查询联系人,则应使用正则表达式,但可能效率不高。

db.contact.findOne({firstName: /^adam$/i, lastName: /^peter$/i})

如果您始终将这些名称值保存为小写,并以小写形式查询

,则会好得多
db.contact.findOne({firstName: 'adam', lastName: 'peter'})

答案 2 :(得分:0)

假设您正在应用的规则是:

  • 如果是一个单词,则可以匹配任何字段
  • 两个字的意思是"名字姓氏"

在这种情况下,你不能使用文本索引,而是需要在mongo搜索之前做一些工作。

首先,在空白处拆分单词,然后确定是否有一个或两个单词。如果有一个单词,请检查所有字段。如果有两个,那么只检查第一个名字对第一个名字,第二个单词对着姓氏。

// assuming input is in variable call 'term'
var words = term.trim().split(/\s+/) || [];

if(words.length === 0) {
    return;
}
var first = new RegExp(words[0], 'i');
if(words.length === 2) {
    var second = new RegExp(words[1], 'i');
    return Contact.find({firstName: first, lastName: second});
else if(words.length === 1) {
    return Contact.find({$or: [ {firstName: first}, {lastName: first}, {email: first}]})
}

此外,根据您的集合的大小,最好将其包装到Meteor方法中,以便在服务器上进行搜索。否则,您必须在客户端上发布整个集合才能进行搜索。对于一个小集合来说可能没问题。

更新:

根据您的示例,我认为您的规则是: 1.搜索项与AND运算符组合(例如,Adam Pet返回两行,而不是三行)。 2.搜索术语使用正则表达式匹配(即使宠物匹配也不是任何单词)。

规则2意味着文本索引不起作用,因此您需要使用$和$或每个项目构建复杂的正则表达式查询文档:

// assuming input is in variable call 'term'
var words = term.trim().split(/\s+/) || [];
var query = {
    "$and": []
};
words.forEach(function(token) {
    var reg = new RegExp(token);
    var innerQ = {"$or": [ {firstName: reg}, {lastName: reg}, {email: reg}]};
    query["$and"].push(innerQ);
});
return Contact.find(query);