如何用Elasticsearch匹配名字和姓氏?

时间:2019-10-22 16:50:33

标签: elasticsearch

典型的Elasticsearch JSON响应类似于:

[
    {
        "_index": "articles",
        "_id": "993",
        "_score": 10.443843,
        "_source": {
            "title": "This is a test title",
            "authors": [
                 {
                      first_name: 'john',
                      last_name: 'smith'
                 },

我如何查询作者为“约翰·史密斯”的所有文章?目前我有:

        const {
            hits: { hits }
        } = await client.search({
            index: "articles",
            body: {
                query: {
                    bool: {
                        should: [
                            {
                                match: {
                                    "authors.first_name": "john"
                                }
                            },
                            {
                                match: {
                                    "authors.first_name": "Smith"
                                }
                            }
                        ]
                    }
                }
            }
        });

但这会返回名字或姓氏是john或smith的文章,而不是作者为“ john smith”的文章。

2 个答案:

答案 0 :(得分:1)

我认为您在此面临nested vs. object dilemma。通过将authors字段的类型更改为嵌套类型(您没有共享索引映射,所以我在这里假设)并使用此查询,可以实现您想要的

{
   "query":{
      "nested":{
         "path":"authors",
         "query":{
            "bool":{
               "must":[
                  {
                     "match":{
                        "authors.firstName":{
                           "query":"john"
                        }
                     }
                  },
                  {
                     "match":{
                        "authors.lastName":{
                           "query":"Smith"
                        }
                     }
                  }
               ]
            }
         }
      }
   }
}

希望有帮助。

答案 1 :(得分:0)

在这种情况下,您使用“应该”语句,可以解释为

firstname:john OR lastname:smith

可以很容易地用“必须”来解决,可以解释为

firstname:john AND lastname:smith

就像rob在回应中提到的那样,嵌套vs对象确实是一个难题。

但是当您处理一系列信息时,就会出现这种困境。

例如,您有以下条目

条目1

   {
      "serviceType": "mysql",
      "allowedUsers": [
        {
          "firstName": "Daniel",
          "lastName": "Acevedo"
        },
        {
          "firstName": "John",
          "lastName": "Smith"
        },
        {
          "firstName": "Mike",
          "lastName": "K"
        }
      ]
    }

然后您进行以下搜索

{
  "size": 10,
  "query": {
    "query_string": {
      "query": "firstName:john AND lastName:acevedo"
    }
  }
}

您将在文档中具有匹配项,因为因为firstName和lastName都与您的文档匹配,即使它们在不同的用户对象中匹配也是如此。这是对象映射的一个例子。

在这种情况下,没有解决方法,您必须使用NESTED映射才能完成自然匹配。

在您的特定情况下,我认为您没有遇到这种情况,因此使用对象和必须(AND而不是应该(OR)查询)应该可以。

如果您需要进一步的解释,请告诉我,我将进行更详细的编辑。

欢呼。