简体   繁体   English

PHP弹性搜索过滤查询字符串搜索

[英]PHP Elastic Search Filtered Query String Search

All would like to use the filtered query where results should contain data from the "query_string" and also from the "term - filter" applied. 所有人都希望使用过滤后的查询,其中结果应包含来自“query_string”的数据以及应用的“term - filter”。

GET blog/_search
{
    "query": {
        "filtered": {
            "query": {
                "query_string": {
                    "fields": [ "description" ],
                    "query": "a"                 // or just ""
                }
            },
            "filter": {
                "terms": {
                    "topic_id": [
                        10
                    ]
                }
            }
        }
    }
}

The expected result is: 预期的结果是:

  1. all blog records having letter "a" or "" in it with topic_id is 10. 所有在topic_id中都带有字母“a”或“”的博客记录为10。
  2. also rest of the records where topic_id is 10 even if the description is blank/empty. 即使描述为空/空,其余的记录中的topic_id为10。

So final result should be - the matching records with higher score and should come at the top, then the records just matching the "topic_id" from the filter. 因此,最终结果应该是 - 匹配记录得分较高且应该位于顶部,然后记录与过滤器中的“topic_id”匹配。

One way to achieve this is use muti_fields mapping for description field. 实现此目的的一种方法是使用muti_fields映射来description字段。 One of the fields in multi-field should be non-analyzed. 多字段中的一个字段应该是未分析的。 Once the data has been reindexed you can use a simple bool query to achieve what you want : 重新编制数据后,您可以使用简单的bool查询来实现您想要的效果:

Example

Create Index: 创建索引:

put test
{
    "mappings": {
        "data" : {
            "properties": {
                "description" : {
                    "type": "string",
                     "fields": {
                        "raw" : {"type": "string","index": "not_analyzed"}
                     }
                }
            }   
        }
    }
}

Index Data: 指数数据:

put test/data/1 
{
    "description" : "a",
    "test_id" : 10
}
put test/data/2
{
    "description" : "",
    "test_id" : 10
}

put test/data/3
{
    "description" : "hello",
    "test_id" : 10
}


put test/data/4
{
    "description": "a",
    "test_id" : 20
}

Query: 查询:

post test/data/_search
{
   "query": {
      "filtered": {
         "query": {
            "bool": {
               "disable_coord": "true",
               "should": [
                  {
                     "query_string": {
                        "fields": [
                           "description"
                        ],
                        "query": "a"
                     }
                  },
                  {
                     "constant_score": {
                        "filter": {
                           "term": {
                              "description.raw": ""
                           }
                        },
                        "boost": 0.2
                     }
                  },
                  {
                     "constant_score": {
                        "filter": {
                           "exists": {
                              "field": "description"
                           }
                        },
                        "boost": 0.1
                     }
                  }
               ]
            }
         },
         "filter": {
            "terms": {
               "test_id": [
                  10
               ]
            }
         }
      }
   }
}

Results : 结果:

 "hits": [
         {
            "_index": "test",
            "_type": "data",
            "_id": "1",
            "_score": 0.5113713,
            "_source": {
               "description": "a",
               "test_id": 10
            }
         },
         {
            "_index": "test",
            "_type": "data",
            "_id": "2",
            "_score": 0.29277003,
            "_source": {
               "description": "",
               "test_id": 10
            }
         },
         {
            "_index": "test",
            "_type": "data",
            "_id": "3",
            "_score": 0.097590014,
            "_source": {
               "description": "hello",
               "test_id": 10
            }
         }
      ]

Query Empty string: 查询空字符串:

{
   "query": {
      "filtered": {
         "query": {
            "bool": {
               "disable_coord": "true",
               "should": [
                  {
                     "query_string": {
                        "fields": [
                           "description"
                        ],
                        "query": ""
                     }
                  },
                  {
                     "constant_score": {
                        "filter": {
                           "term": {
                              "description.raw": ""
                           }
                        },
                        "boost": 0.2
                     }
                  },
                  {
                     "constant_score": {
                        "filter": {
                           "exists": {
                              "field": "description"
                           }
                        },
                        "boost": 0.1
                     }
                  }
               ]
            }
         },
         "filter": {
            "terms": {
               "test_id": [
                  10
               ]
            }
         }
      }
   }
} 

Result : 结果:

  "hits": [
         {
            "_index": "test",
            "_type": "data",
            "_id": "2",
            "_score": 1.3416407,
            "_source": {
               "description": "",
               "test_id": 10
            }
         },
         {
            "_index": "test",
            "_type": "data",
            "_id": "1",
            "_score": 0.44721356,
            "_source": {
               "description": "a",
               "test_id": 10
            }
         },
         {
            "_index": "test",
            "_type": "data",
            "_id": "3",
            "_score": 0.44721356,
            "_source": {
              "description": "hello",
               "test_id": 10
            }
         }
      ]

Have you considered using wildcard query? 您是否考虑过使用通配符查询? Check this query it will work fine for you. 检查此查询它将适合您。

all blog records having letter "a" in it with topic_id is 10. 所有带有topic_id的字母“a”的博客记录都是10。

{
  "filter": {
    "and": [
      {
        "in": {
          "topic_id": [
            "10"
          ]
        }
      },
      {
        "query": {
          "filtered": {
            "filter": {
              "bool": {
                "should": [
                  {
                    "query": {
                      "wildcard": {
                        "description": {
                          "value": "*a*"
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    ]
  }
}

Also rest of the records where topic_id is 10 even if the description is blank/empty. 即使描述为空/空,其余的记录其中topic_id为10。 This will return all the other records that doesn't match the wildcard. 这将返回与通配符不匹配的所有其他记录。

{
  "filter": {
    "and": [
      {
        "in": {
          "topic_id": [
            "10"
          ]
        }
      },
      {
        "not": {
          "query": {
            "filtered": {
              "filter": {
                "bool": {
                  "should": [
                    {
                      "query": {
                        "wildcard": {
                          "description": {
                            "value": "*a*"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    ]
  }
}

To find only the empty " " description fields with topic_id 10. try this, 要仅使用topic_id 10查找空的“”描述字段,请尝试以下操作,

{
  "filter": {
    "and": [
      {
        "in": {
          "topic_id": [
            "10"
          ]
        }
      },
      {
        "query": {
          "filtered": {
            "filter": {
              "script": {
                "script": "_source.description.length() == 0"
              }
            }
          }
        }
      }
    ]
  }
}

For ES 2.x 适用于ES 2.x.

Using a bool query should do the trick. 使用bool查询应该可以解决问题。

Here's the query I will use: 这是我将使用的查询:

GET blog/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "query_string": {
            "fields": [ "description" ],
              "query": "a"
          }
        }
      ],
      "must": [
        {
          "terms": {
            "topic_id": [
              10
            ]
          }
        }
      ]
    }
  }
}

Here, the should clause of the bool query will tell Elassticsearch that document matching the query_string should be returned. 在这里, should在布尔查询的WHERE子句会告诉Elassticsearch该文档匹配query_string应返回。 In the query_string consider using wildcards if you want to match any document containing a . query_string如果要匹配包含a任何文档,请考虑使用通配符。 For example "query_string": { "query": "*a*" } 例如"query_string": { "query": "*a*" }

The must clause in the other hand will tell that, for considering the document a valid match, it must contain 10 in the topic_id field. 另一方面, must子句将告诉我,为了将文档视为有效匹配,它必须在topic_id字段中包含10 Wether the should clause could or could not match. 这个should条款可以匹配也可以不匹配。

Bool filter 布尔过滤器

I hope this could help you. 我希望这可以帮到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM