Elasticsearch:搜索包含对象数组的字段,忽略某些/不同的排名

时间:2016-03-09 21:42:43

标签: elasticsearch

我有以下结构的对象:

{ "contents" : [ { "type": "A", "content": "something"},
                 { "type": "B", "content": "else"} ]}

(这只是一个例子,A或B可能存在或不存在,也可能存在C等。)

我想在数组的内容中搜索,但只搜索“A”类型的内容。在其他时候,如果文本包含在“A”中,我想将结果排名更高。

这可以进行弹性搜索吗?几个必须似乎没有帮助,因为我需要确保A有内容,而不是A或B有内容和A存在。

我不想改变索引对象的结构。

非常感谢

1 个答案:

答案 0 :(得分:1)

让我们先为您的结构添加映射:

POST test_index/test_type/_mapping
{
   "test_type": {
      "properties": {
         "contents": {
            "type": "nested",
            "properties": {
               "type": {
                  "type": "string"
               },
               "content": {
                  "type": "string"
               }
            }
         }
      }
   }
}

现在让我们添加一些示例文档:

POST test_index/test_type/1
{
  "contents": [
    {
      "type": "A",
      "content": "one two three"
    },
    {
      "type": "B",
      "content": "four five six"
    }
  ]
}

POST test_index/test_type/2
{
  "contents": [
    {
      "type": "A",
      "content": "one two three four"
    },
    {
      "type": "B",
      "content": "four five six"
    }
  ]
}

POST test_index/test_type/3
{
  "contents": [
    {
      "type": "A",
      "content": "one two three four"
    },
    {
      "type": "B",
      "content": "five six"
    }
  ]
}

POST test_index/test_type/4
{
  "contents": [
    {
      "type": "A",
      "content": "one two three"
    },
    {
      "type": "B",
      "content": "five six"
    }
  ]
}

现在让我们查询字符串" four"根据您指定的条件在content字段中:

POST test_index/test_type/_search
{
   "query": {
      "nested": {
         "path": "contents",
         "query": {
            "bool": {
               "should": [
                  {
                     "bool": {
                        "must": [
                           {
                              "match": {
                                 "contents.type": "A"
                              }
                           },
                           {
                              "match": {
                                 "contents.content": "four"
                              }
                           }
                        ]
                     }
                  },
                  {
                     "match": {
                        "contents.content": "four"
                     }
                  }
               ]
            }
         }
      }
   }
}

结果:

{
   "took": 3,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 3,
      "max_score": 1.6228913,
      "hits": [
         {
            "_index": "test_index",
            "_type": "test_type",
            "_id": "3",
            "_score": 1.6228913,
            "_source": {
               "contents": [
                  {
                     "type": "A",
                     "content": "one two three four"
                  },
                  {
                     "type": "B",
                     "content": "five six"
                  }
               ]
            }
         },
         {
            "_index": "test_index",
            "_type": "test_type",
            "_id": "2",
            "_score": 1.0997313,
            "_source": {
               "contents": [
                  {
                     "type": "A",
                     "content": "one two three four"
                  },
                  {
                     "type": "B",
                     "content": "four five six"
                  }
               ]
            }
         },
         {
            "_index": "test_index",
            "_type": "test_type",
            "_id": "1",
            "_score": 0.20286141,
            "_source": {
               "contents": [
                  {
                     "type": "A",
                     "content": "one two three"
                  },
                  {
                     "type": "B",
                     "content": "four five six"
                  }
               ]
            }
         }
      ]
   }
}

在这里,您可以看到类型为" A"的文档。和字符串"四"在内容中排名高于doc的内容" four"在类型" B"。