1

假设我在用户/数据中有一个用户对象:

{"_id": 123, "name": "Bob"}

并且用户有多个宠物,宠物文档如下所示:

{"_id": 1423, "owner": 123, "type": "cat", "name": "Prince McNugget"}
{"_id": 1830, "owner": 123, "type": "dog", "name": "Tarley"}

在弹性搜索中执行快速(即索引)搜索以查找所有者为 123 的所有宠物文档的正确方法是什么(或什么是好的选择) ?

我已经阅读了建议使用字段为“not_analyzed”的映射的“精确匹配”问题的答案,但我假设“not_analyzed”的字段未编入索引,因此数据库必须执行类似于全表扫描的操作(我在这里与 SQL 进行比较)以得出结果。这对我来说是不可接受的——我需要它是一个索引搜索。

4

3 回答 3

2

您可以term query在宠物上使用:http ://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-term-query.html

{
  "query": {
    "term" : { "owner" : 123 }
  }
}

在 ES 中,除非您配置不对其进行索引,否则所有内容都会被索引,因此默认情况下它应该很快。

编辑:“not_analyzed”正如 mcollin 解释的那样。它只是告诉 ES 不要分析数据(保留我们传递的数据),除非您指定"index" : "no".

于 2013-12-06T08:39:27.187 回答
1

我会假设“not_analyzed”的字段没有被索引

这是一个容易做出的假设,但也是一个错误的假设。在 ES 中,'not_analyzed' 表示该字段中的数据未拆分为标记(分析)。数据仍然非常索引。

在 ES 中搜索的最快方法是使用过滤器。从第一个查询 DSL 页面:

过滤器非常方便,因为它们执行比普通查询好一个数量级,因为不执行评分并且它们被自动缓存。

由于过滤器要快得多,所以最快的查询几乎总是过滤后的查询:

{
    "query": {
        "filtered": {
            "query": { 'match_all' : { } },
            "filter": {
                { "term": { "owner": 123 }}
            }
        }
    }
}

过滤查询页面所述,过滤查询的默认查询是match_all,因此该查询可以进一步缩短为:

{
    "query": {
        "filtered": {
            "filter": {
                { "term": { "owner": 123 }}
            }
        }
    }
}

过滤器的限制是它们是布尔值。文档要么完全匹配过滤器,要么不匹配。为了性能,建议尽可能使用过滤器进行约束,然后使用查询进行进一步匹配。

我已经构建了一个查询构建器,它解析 HTML 表单,然后提交搜索参数。构建器检查每个搜索参数中的通配符(? 或 *),如果存在,则使用通配符查询。如果没有,它会添加一个过滤器。我提供 UI 按钮,使用户可以通过单击数据轻松执行精确搜索。当他们使用这些时,搜索会命中过滤器并且速度很快。在等待几毫秒后,他们还可以键入string*并获取他们想要的内容。

这是我的查询生成器的通用片段:

var filters = [], queries = [];
var searchVal = ..., searchField = ...;

var getWild = function (field, val, boost) {
    var wc = { wildcard: { } };
    wc.wildcard[field] = { value: val, boost: (boost || 1) };
    return wc;
};

if (searchVal) {
    if (/\*|\?/.test(searchVal)) {
        queries.push(getWild(searchField, searchVal);
    }
    else {
        filters.push({ term: {searchField: searchVal}});
    }
}

我使用And过滤器来约束所有精确匹配(日期范围、uid 约束等),然后将其余查询作为filtered -> bool查询。它运行得非常好,我的 3 节点小型 ES 集群有 133,000,000 个文档,速度足够快。

于 2015-07-01T08:15:11.750 回答
0

对于您的用例,es的关系特性很有趣。这些允许诸如has_parent 之类的查询,您可以在其中搜索确切的 id。除此之外,提到的术语查询是正确的。

于 2015-06-05T16:33:26.400 回答