【问题标题】:Search exact phrase by multiple fields in ElasticSearch在 ElasticSearch 中按多个字段搜索确切的短语
【发布时间】:2019-11-24 16:54:55
【问题描述】:

我有带有属性的产品。例如“名称”、“品牌”、“颜色”、“类别”、“尺寸”。当我按短语搜索产品时(例如“black jack puma”),除了与“brand”=“puma”、“color”=“black”、“category”=“jacket”或“name”= “黑色彪马夹克”,我也有偏配的产品。我的查询是:

'match'    => [
    'message'   => [
        'query'     => "black puma jacket"
        'operator'  => 'and'
    ]
]

我也试过这个查询:

'multi_match'   => [
    'fields'    => [
        'brand',
        'color',
        'name'
    ],
    'query' => 'puma black jacket',
]

我的查询有什么问题?

更新:

我的映射:

'brand' => [
    'type'      => 'string',
    'fields'    => [
        'keyword'   => [
            'type'              => 'string',
            'analyzer'          => 'slug',
            'index_options'     => 'docs',
        ],
        'raw'   => [
            'type'      => 'string',
            'analyzer'  => 'format',
        ]
    ]
],
'color' => [
    'type'  => 'string',
    'fields'    => [
        'keyword'   => [
            'type'              => 'string',
            'analyzer'          => 'slug',
            'index_options'     => 'docs',
        ],
        'raw'   => [
            'type'      => 'string',
            'analyzer'  => 'format',
        ]
    ]
],
'category' => [
    'type'  => 'string',
    'fields'    => [
        'keyword'   => [
            'type'              => 'string',
            'analyzer'          => 'slug',
            'index_options'     => 'docs',
        ],
        'raw'   => [
            'type'      => 'string',
            'analyzer'  => 'format',
        ]
    ]
],
'category_id' => [
    'type'  => 'integer',
],
'store_id' => [
    'type'  => 'integer',
],
'size' => [
    'type'  => 'string',
    'fields'    => [
        'keyword'   => [
            'type'              => 'string',
            'analyzer'          => 'slug',
            'index_options'     => 'docs',
        ],
        'raw'   => [
            'type'      => 'string',
            'analyzer'  => 'format',
        ]
    ]
],
'material' => [
    'type'  => 'string',
    'fields'    => [
        'keyword'   => [
            'type'              => 'string',
            'analyzer'          => 'slug',
            'index_options'     => 'docs',
        ],
        'raw'   => [
            'type'      => 'string',
            'analyzer'  => 'format',
        ]
    ]
],
'type' => [
    'type'  => 'string',
    'fields'    => [
        'keyword'   => [
            'type'              => 'string',
            'analyzer'          => 'slug',
            'index_options'     => 'docs',
        ],
        'raw'   => [
            'type'      => 'string',
            'analyzer'  => 'format',
        ]
    ]
],
'volume' => [
    'type'  => 'string',
    'fields'    => [
        'keyword'   => [
            'type'              => 'string',
            'analyzer'          => 'slug',
            'index_options'     => 'docs',
        ],
        'raw'   => [
            'type'      => 'string',
            'analyzer'  => 'format',
        ]
    ]
],
'price' => [
    'type'  => 'float',
],
'desc' => [
    'type'  => 'string',
],
'sku' => [
    'type'  => 'string',
    'index' => 'not_analyzed'
],
'picture' => [
    'type'  => 'string',
    'index' => 'not_analyzed'
]   

];

【问题讨论】:

  • 尝试查询:{ bool : { must: { match: { text: 'black puma jack'} } } }
  • 尝试查询:{ bool : { must: { match: { text: 'black puma jack'} } } }
  • 不。此查询返回空结果
  • 请提供一个示例,说明您正在尝试实现的目标以及与您的映射相关的详细信息。谢谢
  • @AssaelAzran,我放置了我的映射。我的目标是仅搜索属性或名称与我的查询字符串匹配的项目。如果我搜索“黑色夹克”,我只想查看存在“黑色”和“夹克”的项目(无论在哪里 - 产品属性或名称),并且只传递“黑色”或“夹克”匹配的项目。如果我在 DB 10 中有颜色为“黑色”的项目和 5 个类型或类别为“夹克”的项目,并且只有 2 个颜色为“黑色”并输入“夹克”的项目,搜索结果必须只包含 2 个项目。跨度>

标签: elasticsearch


【解决方案1】:

根据您的映射和要求,我认为cross_fields 可能会对您有所帮助。

只有 2 个属性(颜色和类别)的示例:

发布一些文件:

POST my_index/_doc/1
{    
    "color": "black",
    "category": "1"
}

POST my_index/_doc/2
{    
    "color": "black",
    "category": "2"
}

POST my_index/_doc/3
{    
    "color": "black",
    "category": "3"
}

POST my_index/_doc/4
{   
    "color": "1",
    "category": "jacket"
}

POST my_index/_doc/5
{   
    "color": "2",
    "category": "jacket"
}

POST my_index/_doc/6
{   
    "color": "3",
    "category": "jacket"
}

POST my_index/_doc/6
{   
    "color": "3",
    "category": "jacket"
}

POST my_index/_doc/7
{   
    "color": "black",
    "category": "jacket"
}

POST my_index/_doc/8
{   
    "color": "black",
    "category": "jacket"
}

您的搜索查询将如下所示:

GET my_index/_search
{
  "query": {
    "multi_match": {
      "query": "black jacket",
      "fields": [],
      "type": "cross_fields",
      "operator": "and",
      "analyzer": "standard"
    }
  }
}

结果:

{
 "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.2192403,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "7",
        "_score" : 1.2192403,
        "_source" : {
          "color" : "black",
          "category" : "jacket"
        }
      },
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "8",
        "_score" : 1.2192403,
        "_source" : {
          "color" : "black",
          "category" : "jacket"
        }
      }
   ]
}

如您所见,我们没有得到所有其他部分匹配 blackjacket

的文档

希望有帮助

【讨论】:

  • 谢谢,您的示例按我的意愿工作。还有一个问题——“multi_match”中的“fields”参数不能为空?仅当我设置确切的字段列表时,您的示例才对我有用。
  • 你的 elasticsearch 版本是多少?
  • “版本”:{“数字”:“2.3.1”,“build_timestamp”:“2016-04-04T12:25:05Z”,“lucene_version”:“5.5.0”}
  • 根据文档 如果没有提供字段,multi_match 查询默认为 index.query.default_field 索引设置,而这又默认为所有字段 这与 7.4 相关.在 2.3 中,此文档不存在,所以我认为它不受支持。 elastic.co/guide/en/elasticsearch/reference/2.3/… , elastic.co/guide/en/elasticsearch/reference/7.4/…
  • 知道了。无论如何,您的示例按我的意愿工作并设置字段列表不是问题。
【解决方案2】:

根据您的要求,我会将品牌、颜色和类别分组到一个字段中,然后应用词组匹配。您需要修改产品映射

PUT /products
{
  "mappings":{
    "properties":{
      "brand": {
        "type": "text",
        "copy_to": "name",
        ...
      },
      "color": {
        "type": "text",
        "copy_to": "name",
        ...
      },
      "category": {
        "type": "text",
        "copy_to": "name",
        ...
      },
      "name": {
        "type": "text"
      },
      ...
    }
  }
}

在名称字段上使用词组匹配进行搜索

GET /products/_search
{
  "query":{
    "match_phrase": {
      "name": {
        "query": {
          "name": "black puma jacket",
          "slop": 1
        }
      }
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    • 2022-01-20
    • 2015-10-19
    • 2021-08-19
    • 1970-01-01
    相关资源
    最近更新 更多