Elasticsearch多个搜索条件

时间:2014-07-23 21:48:25

标签: elasticsearch

我正在尝试以下列方式执行elasticsearch查询:

  • 搜索查询
  • 功能得分查询 - 其中一个位于嵌套位置,另一个用于提升与特定类型匹配的文档得分
  • 文档必须与{ verified: true }
  • 匹配

我有一个名为users的索引,在该索引中有两种类型 - type1type2,每种类型都有完全相同的映射。 users索引中的示例文档是:

{
  name: 'Brian Fantana',
  location: {
    coordinates: {
      lat: 22.266858, 
      lon: 114.152069
    },
    country: 'United States',
    city: 'New York'
  },
  verified: true
}

和映射:

{
  name: { type: 'string' },
  location: {
    properties: {
      coordinates: {
        type: 'geo_point',
        lat_lon: true
      }
    }
  },
  verified: { type: 'boolean' }
}

我尝试了以下内容:

{
  query: {
    bool: {
      must: { match: { verified: true } }
    },
    query_string: {
      query: <query_string>
    },
    function_score: {
      functions: [{
        script_score: "doc['_type'].value == 'type1' ? _score * 100 : _score"
      }]
    },
    nested: {
      path: 'location',
      query: {
        function_score: {
          functions: [{
            gauss: {
              'location.coordinates': <location>,
              scale: '50km'
            }
          }]
        }
      }
    }
    }]
  }
}

显然,我不知道如何组合这样的查询。抱歉是个白痴。

2 个答案:

答案 0 :(得分:1)

这就是我想出的。这是针对ES v1.2.2运行的 - 这很重要,因为早期版本没有像这样为脚本公开_type字段。在1.3.0中,不推荐使用动态脚本。

您可以看到我正在索引多个文档以证明评分函数的成功应用。

    #!/bin/sh
echo "--- delete index"
curl -X DELETE 'http://localhost:9200/so_multi_search/'
echo "--- create index and put mapping into place"
curl -XPUT "http://localhost:9200/so_multi_search/?pretty=true" -d '{
    "mappings": {
        "type1": {
            "properties": {
                "group":  { "type": "integer" },
                "verified": { "type": "boolean" },
                "name": { "type": "string" },
                "location": {
                    "properties": {
                        "coordinates": {
                            "type": "geo_point",
                            "lat_lon": true
                        }
                    }
                }
            }
        },
        "type2": {
            "properties": {
                "group":  { "type": "integer" },
                "verified": { "type": "boolean" },
                "name": { "type": "string" },
                "location": {
                    "properties": {
                        "coordinates": {
                            "type": "geo_point",
                            "lat_lon": true
                        }
                    }
                }
            }
        }
    },
    "settings" : {
        "number_of_shards" : 1,
        "number_of_replicas" : 0
    }
}'
echo "--- index users by POSTing"
curl -XPOST "http://localhost:9200/so_multi_search/type1" -d '{
    "name": "Brian Fantana",
    "location": {
        "coordinates": {
              "lat": 40.712784,
              "lon": -74.005941
        },
        "country": "United States",
        "city": "New York"
    },
    "group": 1,
    "verified": true
}'
curl -XPOST "http://localhost:9200/so_multi_search/type2" -d '{
    "name": "Brian Fantana",
    "location": {
        "coordinates": {
              "lat": 40.712784,
              "lon": -74.005941
        },
        "country": "United States",
        "city": "New York"
    },
    "group": 2,
    "verified": true
}'
curl -XPOST "http://localhost:9200/so_multi_search/type2" -d '{
    "name": "Anna Fantana",
    "location": {
        "coordinates": {
              "lat": 40.82,
              "lon": -73.5
        },
        "country": "United States",
        "city": "New York"
    },
    "group": 2,
    "verified": true
}'
echo "--- flush index"
curl -XPOST 'http://localhost:9200/_flush'
echo "--- search the users"
curl -XGET "http://localhost:9200/so_multi_search/_search?pretty=true" -d '{
    "query": {
        "filtered": {
            "query": {
                "function_score": {
                    "functions": [
                        {
                            "filter": {
                                "query": {
                                    "query_string": {
                                        "default_field": "name",
                                        "query": "Fantana"
                                    }
                                }
                            },
                            "script_score": {
                                "script": "doc[\"_type\"].value == \"type1\" ? _score * 100 : _score"
                            }
                        },
                        {
                            "gauss": {
                                "location.coordinates": {
                                    "origin": "40.712784, -74.005941",
                                    "scale": "50km"
                                }
                            }
                        }
                    ]
                }
            },
            "filter": {
                "query": {
                    "bool": {
                        "must": {
                            "match": {
                                "verified": true
                            }
                        }
                    }
                }
            }
        }
    }
}'

输出:

--- delete index
{"acknowledged":true}--- create index and put mapping into place
{
  "acknowledged" : true
}
--- index users by POSTing
{"_index":"so_multi_search","_type":"type1","_id":"bAPnG5KfQXu_QIgGvY1mmA","_version":1,"created":true}{"_index":"so_multi_search","_type":"type2","_id":"XtCC8L6QRKueCdPsncAOpg","_version":1,"created":true}{"_index":"so_multi_search","_type":"type2","_id":"qlXiyXpQTySCLdMcL-DILw","_version":1,"created":true}--- flush index
{"_shards":{"total":8,"successful":8,"failed":0}}--- search the users
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 100.0,
    "hits" : [ {
      "_index" : "so_multi_search",
      "_type" : "type1",
      "_id" : "bAPnG5KfQXu_QIgGvY1mmA",
      "_score" : 100.0,
      "_source":{
    "name": "Brian Fantana",
    "location": {
        "coordinates": {
              "lat": 40.712784,
              "lon": -74.005941
        },
        "country": "United States",
        "city": "New York"
    },
    "group": 1,
    "verified": true
}
    }, {
      "_index" : "so_multi_search",
      "_type" : "type2",
      "_id" : "XtCC8L6QRKueCdPsncAOpg",
      "_score" : 1.0,
      "_source":{
    "name": "Brian Fantana",
    "location": {
        "coordinates": {
              "lat": 40.712784,
              "lon": -74.005941
        },
        "country": "United States",
        "city": "New York"
    },
    "group": 2,
    "verified": true
}
    }, {
      "_index" : "so_multi_search",
      "_type" : "type2",
      "_id" : "qlXiyXpQTySCLdMcL-DILw",
      "_score" : 0.5813293,
      "_source":{
    "name": "Anna Fantana",
    "location": {
        "coordinates": {
              "lat": 40.82,
              "lon": -73.5
        },
        "country": "United States",
        "city": "New York"
    },
    "group": 2,
    "verified": true
}
    } ]
  }
}

答案 1 :(得分:0)

好的,在阅读了更多查询DSL之后,这是我的解决方案:

query: {
    function_score: {
        query: {
            query_string: {
                query: query + '*'
            },
        },
        filter: {
            term: {
                verified: true
            }
        },
        functions: [{
            script_score: {
                script: "doc['_type'].value == 'type1' ? _score * 1000 : _score"
            },
            gauss: {
                'location.coordinates': {
                    origin: [location.latitude, location.longitude],
                    scale: '20km'
                } 
            }
        }]
    }
}