【问题标题】:MongoDB & Spring Data - Searching for a user by firstname/lastnameMongoDB & Spring Data - 按名字/姓氏搜索用户
【发布时间】:2015-08-01 08:25:02
【问题描述】:

我有以下收藏:

User {
   firstname,
   lastname
}

我想按名字和/或姓氏(名字/姓氏/名字+姓氏)搜索用户。

我有什么:

 Criteria criteria = new Criteria();
 criteria.orOperator(Criteria.where("firstname").regex(searchQuery),Criteria.where("lastname").regex(searchQuery));

上面的问题是我可以按名字或姓氏搜索,但不能同时搜索(例如,“John Smith”是不可能的,而“John”或“Smith”是可能的。 这是因为 orOperator 而发生的,我看不到任何 andOr 或类似的东西。

例如如果我的数据库中有“John Smith”,我可以通过查询“John”、“Smith”、“John Smith”来找到他(就像在 facebook 中一样)

编辑:

String queryx[] = searchQuery.split(" ");
for(String q : queryx) {
    criteria.orOperator(Criteria.where("firstname").regex(searchQuery),Criteria.where("lastname").regex(q));
}

显示结果,但它在我的控制台中给出以下错误:

  Due to limitations of the com.mongodb.BasicDBObject, you can't add a second '$or' expression specified as '$or : [ { "firstname" : { "$regex" : "john smith"}} , { "lastname" : { "$regex" : "smith"}}]'. Criteria already contains '$or : [ { "firstname" : { "$regex" : "john smith"}} , { "lastname" : { "$regex" : "john"}}]'.

编辑2:

String queryx[] = searchQuery.split(" ");
   ArrayList<Criteria> orOperators = new ArrayList<Criteria>();
for(String q : queryx) {
    Criteria criteria = new Criteria();
    criteria.orOperator(Criteria.where("firstname").regex(searchQuery),Criteria.where("lastname").regex(q));
    orOperators.add(criteria);
}

Criteria [] orArray = orOperators.toArray(new Criteria[orOperators.size()]);
Criteria c = Criteria.where("firstname").regex(searchQuery);
c.orOperator(orArray);

Query query = new Query(c).limit(limit);
return mongoOperations.find(query, User.class);

编辑 3:

String queryx[] = searchQuery.split(" ");
ArrayList<Criteria> cr = new ArrayList<Criteria>();
for (String q : queryx) {
    Criteria criteria = new Criteria();
    criteria.orOperator(Criteria.where("firstname").regex(q),
            Criteria.where("lastname").regex(q));
    cr.add(criteria);
}

Query query = new Query();
for (Criteria cri : cr) {
    query.addCriteria(cri); //this is the problem
}

return mongoOperations.find(query, User.class);

错误:

 Due to limitations of the com.mongodb.BasicDBObject, you can't add a second 'null' criteria. Query already contains '{ "$or" : [ { "firstname" : { "$regex" : "john smith"}} , { "lastname" : { "$regex" : "john"}}]}'.

【问题讨论】:

    标签: mongodb mongodb-query spring-data criteria-api database


    【解决方案1】:

    要搜索名字和姓氏,您可以轻松地执行以下操作:

    String queryx[] = searchQuery.split(" ");
    ArrayList<Criteria> cr = new ArrayList<Criteria>();
    for (String q : queryx) {
        Criteria fCriteria = Criteria.where("firstname").regex(q);
        cr.add(fCriteria);
        Criteria lCriteria = Criteria.where("lastname").regex(q);
        cr.add(lCriteria);
    }
    Criteria c = cr.remove(0);
    Criteria [] orArray = orOperators.toArray(new Criteria[orOperators.size()]);
    c.orOperator(orArray);
    query.addCriteria(c); //this is the problem
    return mongoOperations.find(query, User.class);
    

    【讨论】:

    • 感谢您的评论,但它不起作用(我试过了)。它会在名字和姓氏与 searchQuery 匹配时进行查找。为了清楚起见,我编辑了我的帖子。
    • 仍然不清楚您在搜索什么。当searchQuery 是“John Smith”时,你想找到那个用户吗?如果是这种情况,您手动将字符串分成两部分并仅使用 orOperator。
    • 没错。就像在 Facebook 中一样,无论您搜索名字还是姓氏或名字+姓氏,它都会检索用户。我在原帖中使用了 orOperator,但我不知道如何组合 firstname+lastname。
    • 所以我的建议是拆分 searchQuery 以防它在更新后的帖子中有空格
    • 感谢您的评论。当我只输入 1 个名称时,我首先收到一个数组越界错误(因为没有查询 [1] 值)。但即使我输入“John Smith”,我也会收到以下错误:由于 com.mongodb.BasicDBObject 的限制,您无法添加指定为 '$or 的第二个 '$or' 表达式:[ { "firsname" : { "$regex" : "john"} , "$and" : [ { "lastname" : { "$regex" : "smith"}}]}]'。条件已经包含 '$or : [ { "lastname" : { "$regex" : "john smith"}}]'.] 的根本原因
    【解决方案2】:

    我用过,成功了

    List<Criteria> userNameCriteriaList = Lists.newArrayList();
    
    for (String key: keyWords) {
        Criteria criteria = new Criteria();
        criteria.orOperator(
             where(FIRST_NAME).regex(regex, "i"),
             where(LAST_NAME).regex(regex, "i")
        );
        userNameCriteriaList.add(criteria);
    }
    
    return new Criteria().andOperator(userNameCriteriaList.toArray(new Criteria[0]));
    

    【讨论】:

      【解决方案3】:

      不使用标准,您只需在您的实体'User' 中的'firstname' 和'lastname' 上添加@TextIndexed 并执行以下操作:

      @Query("{ $text: { $search: ?0 } }")
      List<User> searchUsers(String search);
      

      它适用于所有这些搜索查询:

      • “约翰”
      • “约翰·多伊”
      • "doe john"
      • “能源部”

      【讨论】:

        猜你喜欢
        • 2016-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-02
        • 1970-01-01
        • 2020-01-19
        • 1970-01-01
        相关资源
        最近更新 更多