【问题标题】:searching in mongo specifically专门在mongo中搜索
【发布时间】:2016-06-18 19:43:24
【问题描述】:

我有一个问题,假设我有一个名为联系人的集合:

[
    {"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" 然后我想得到第一个只有亚当和彼得的结果。

我在我的应用程序中使用meteor + mongo + react

任何建议/推荐将不胜感激。

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

场景:

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

所以:

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

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

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

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

【问题讨论】:

  • 可能我想先在 mongo 中查询,而不是去流星或响应测试。

标签: mongodb search meteor reactjs


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    如果你总是将这些名称值保存为小写,并以小写查询会更好

    db.contact.findOne({firstName: 'adam', lastName: 'peter'})
    

    【讨论】:

      【解决方案3】:

      假设您应用的规则是:

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

      在这种情况下,您不能使用文本索引,而是需要在 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 意味着文本索引不起作用,因此您需要为每个项目使用 $and 和 $or 构建一个复杂的正则表达式查询文档:

      // 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);
      

      【讨论】:

      • 太棒了,但是我实际上可以输入任意数量的单词,以便在我的所有联系人字段中进行专门搜索。我实际上有更多字段,例如 mobileNumber、phoneNumber... 用户应该能够输入他们认为相关的任何内容。例如:用户可以输入 Adam 04-1234-1234。所以它并不总是名字 + 姓氏。
      • 在这种情况下你能澄清你的规则吗?听起来您可能想使用 AND 而不是 OR 来搜索每个标记?那正确吗?在这种情况下,我将编辑我的答案。
      猜你喜欢
      • 1970-01-01
      • 2022-07-20
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 2013-08-08
      • 1970-01-01
      • 2021-03-05
      • 2017-09-17
      相关资源
      最近更新 更多