seo点击排名软件哪家好,网站建设和网络优化请示,办公室装修报价表,网络营销的手段有哪些实时查询
通常对一个通过上面方法写入到 Elasticsearch 的文档#xff0c;在默认的情况下并不马上可以进行搜索。这是因为在 Elasticsearch 的设计中#xff0c;有一个叫做 refresh 的操作。它可以使更改可见以进行搜索的操作。通常会有一个 refresh timer 来定时完成这个操…实时查询
通常对一个通过上面方法写入到 Elasticsearch 的文档在默认的情况下并不马上可以进行搜索。这是因为在 Elasticsearch 的设计中有一个叫做 refresh 的操作。它可以使更改可见以进行搜索的操作。通常会有一个 refresh timer 来定时完成这个操作。这个周期为1秒。这也是我们通常所说的 Elasticsearch 可以实现秒级的搜索。当然这个 timer 的周期也可以在索引的设置中进行配置。如果我们想让我们的结果马上可以对搜索可见我们可以用如下的方法 PUT twitter/_doc/1?refreshtrue { user: GB, uid: 1, city: Beijing, province: Beijing, country: China }
上面的方式可以强制使 Elasticsearch 进行 refresh 的操作当然这个是有代价的。频繁的进行这种操作可以使我们的 Elasticsearch 变得非常慢。另外一种方式是通过设置 refreshwait_for。这样相当于一个同步的操作它等待下一个 refresh 周期发生完后才返回。这样可以确保我们在调用上面的接口后马上可以搜索到我们刚才录入的文档 PUT twitter/_doc/1?refreshwait_for { user: GB, uid: 1, city: Beijing, province: Beijing, country: China }
查询后更新
在关系数据库中我们通常是对数据库进行搜索让后才进行修改。在这种情况下我们事先通常并不知道文档的 id。我们需要通过查询的方式来进行查询让后进行修改。ES 也提供了相应的 REST 接口。 要结合脚本才可以实现 POST twitter/_update_by_query { query: { match: { user: GB } }, script: { source: ctx._source.city params.city;ctx._source.province params.province;ctx._source.country params.country, lang: painless, params: { city: 上海, province: 上海, country: 中国 } } }
存在更新不存在新增
仅在文档事先存在的情况下我们在前面的代码中看到的部分更新才有效。 如果具有给定 id 的文档不存在Elasticsearch 将返回一个错误指出该文档丢失。 让我们了解如何使用更新 API 进行 upsert 操作。 术语 “upsert” 宽松地表示更新或插入即更新文档如果存在否则插入新文档。
doc_as_upsert 参数检查具有给定ID的文档是否已经存在并将提供的 doc 与现有文档合并。 如果不存在具有给定 id 的文档则会插入具有给定文档内容的新文档。 下面的示例使用 doc_as_upsert 合并到 id 为 3 的文档中或者如果不存在则插入一个新文档 POST /catalog/_update/3 { doc: { author: Albert Paro, title: Elasticsearch 5.0 Cookbook, description: Elasticsearch 5.0 Cookbook Third Edition, price: 54.99 }, doc_as_upsert: true }
查询后删除
在关系数据库中我们通常是对数据库进行搜索让后才进行删除。在这种情况下我们事先通常并不知道文档的 id。我们需要通过查询的方式来进行查询让后进行删除。ES 也提供了相应的 REST 接口。 POST twitter/_delete_by_query { query: { match: { city: 上海 } } }
批处理命令_bulk
因为每一次操作都是一个 REST 请求对于大量的数据进行操作的话这个显得比较慢。ES 创建一个批量处理的命令给我们使用。这样我们在一次的 REST 请求中我们就可以完成很多的操作。这无疑是一个非常大的好处。下面我们来介绍一下这个 _bulk 命令。 POST _bulk { index : { _index : twitter, _id: 1} } {user:双榆树-张三,message:今儿天气不错啊出去转转去,uid:2,age:20,city:北京,province:北京,country:中国,address:中国北京市海淀区,location:{lat:39.970718,lon:116.325747}} { index : { _index : twitter, _id: 2 }} {user:东城区-老刘,message:出发下一站云南,uid:3,age:30,city:北京,province:北京,country:中国,address:中国北京市东城区台基厂三条3号,location:{lat:39.904313,lon:116.412754}} { index : { _index : twitter, _id: 3} } {user:东城区-李四,message:happy birthday!,uid:4,age:30,city:北京,province:北京,country:中国,address:中国北京市东城区,location:{lat:39.893801,lon:116.408986}} { index : { _index : twitter, _id: 4} } {user:朝阳区-老贾,message:123,gogogo,uid:5,age:35,city:北京,province:北京,country:中国,address:中国北京市朝阳区建国门,location:{lat:39.718256,lon:116.367910}} { index : { _index : twitter, _id: 5} } {user:朝阳区-老王,message:Happy BirthDay My Friend!,uid:6,age:50,city:北京,province:北京,country:中国,address:中国北京市朝阳区国贸,location:{lat:39.918256,lon:116.467910}} { index : { _index : twitter, _id: 6} } {user:虹桥-老吴,message:好友来了都今天我生日好友来了,什么 birthday happy 就成!,uid:7,age:90,city:上海,province:上海,country:中国,address:中国上海市闵行区,location:{lat:31.175927,lon:121.383328}}
在上面的命令中我们使用了 bulk 指令来完成我们的操作。在输入命令时我们需要特别的注意千万不要添加除了换行以外的空格否则会导致错误。在上面我们使用的 index 用来创建一个文档。为了说明问题的方便我们在每一个文档里特别指定了每个文档的 id。当执行完我们的批处理 bulk 命令后我们可以看到
bulk 指令是高效的因为一个请求就可以处理很多个操作。在实际的使用中我们必须注意的是一个好的起点是批量处理 1,000 到 5,000 个文档总有效负载在 5MB 到 15MB 之间。如果我们的 payload 过大那么可能会造成请求的失败。
使用create批量创建 POST _bulk { create : { _index : twitter, _id: 1} } {user:双榆树-张三,message:今儿天气不错啊出去转转去,uid:2,age:20,city:北京,province:北京,country:中国,address:中国北京市海淀区,location:{lat:39.970718,lon:116.325747}} { index : { _index : twitter, _id: 2 }} {user:东城区-老刘,message:出发下一站云南,uid:3,age:30,city:北京,province:北京,country:中国,address:中国北京市东城区台基厂三条3号,location:{lat:39.904313,lon:116.412754}} { index : { _index : twitter, _id: 3} } {user:东城区-李四,message:happy birthday!,uid:4,age:30,city:北京,province:北京,country:中国,address:中国北京市东城区,location:{lat:39.893801,lon:116.408986}} { index : { _index : twitter, _id: 4} } {user:朝阳区-老贾,message:123,gogogo,uid:5,age:35,city:北京,province:北京,country:中国,address:中国北京市朝阳区建国门,location:{lat:39.718256,lon:116.367910}} { index : { _index : twitter, _id: 5} } {user:朝阳区-老王,message:Happy BirthDay My Friend!,uid:6,age:50,city:北京,province:北京,country:中国,address:中国北京市朝阳区国贸,location:{lat:39.918256,lon:116.467910}} { index : { _index : twitter, _id: 6} } {user:虹桥-老吴,message:好友来了都今天我生日好友来了,什么 birthday happy 就成!,uid:7,age:90,city:上海,province:上海,country:中国,address:中国上海市闵行区,location:{lat:31.175927,lon:121.383328}} index 和 create 的区别。index 总是可以成功它可以覆盖之前的已经创建的文档但是 create 则不行如果已经有以那个 id 为名义的文档就不会成功。
批量删除 POST _bulk { delete : { _index : twitter, _id: 1 }}
批量更新 POST _bulk { update : { _index : twitter, _id: 2 }} {doc: { city: 长沙}}
分页搜索
1.使用from,size分页搜索 深分页性能会有所降低并且from size 最大不能超过 10000 超过10000 ES会直接报错。
例如如果更改 mapping 并希望将所有现有数据重新索引到新索引中您可能没有足够的内存来对所有结果进行排序以返回最后一页的数据。
对于大量的数据而言我们尽量避免使用 fromsize 这种方法。这里的原因是 index.max_result_window 的默认值是 10K也就是说 fromsize 的最大值是1万。搜索请求占用堆内存和时间与 fromsize 成比例这限制了内存。假如你想 hit 从 990 到 1000那么每个 shard 至少需要 1000 个文档
2.使用scroll分页 GET twitter/_search?scroll1m { query: { match: { city: 北京 } }, size: 2 }
这里的 scroll1m表明 Elasticsearch 允许等待的时间是1分钟。如果在一分钟之内接下来的 scroll 请求没有到达的话那么当前的请求的上下文将会丢失。
返回的数据是 { _scroll_id : DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAFh8WWUdCVlRMUllRb3UzMkdqb0IxVnZNUQ, took : 31, timed_out : false, _shards : { total : 1, successful : 1, skipped : 0, failed : 0 } ... }
在这里我们可以看到一个返回的 _scroll_id。这个 _scroll_id 将会被用于接下来的请求。
利用上次请求返回来的 _scroll_id再次请求以获得下一个 page 的信息 GET _search/scroll { scroll: 1m, scroll_id:DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAHC8WWUdCVlRMUllRb3UzMkdqb0IxVnZNUQ }
在这里必须指出的是
这里填写的 scroll_id 是上一个请求返回的值这个 scroll_id 的有效期是我们在第一次搜索时定义的 1m也就是1分钟。如果超过了这个就没有用 如果完成此过程则需要清理上下文因为上下文在超时之前仍会占用计算资源。 如下面的屏幕快照所示您可以使用 scroll_id 参数在 DELETE API 中指定一个或多个上下文 DELTE_search/scroll { scroll_id:DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAHC8WWUdCVlRMUllRb3UzMkdqb0IxVnZNUQ }
注意事项: 使用scroll时数据是一致的不会实时更新生成scroll时数据生成快照有效期到期之前有新增数据 scroll查询不能感知。 scroll占用内存当快照不使用时应当及时清除。 scroll到期后在java程序中查询会抛出异常应当及时捕获处理。
3.使用after_search分页(推荐)
为了避免过度使得我们的 cluster 繁忙通常 Scroll 接口被推荐作为深层次的 scrolling但是因为维护 scroll 上下文也是非常昂贵的所以这种方法不推荐作为实时用户请求。search_after 参数通过提供实时 cursor 来解决此问题。 我们的想法是使用上一页的结果来帮助检索下一页。 我们先创建一些测试数据 POST _bulk { index : { _index : twitter, _id: 1} } {user:双榆树-张三, DOB:1980-01-01, message:今儿天气不错啊出去转转去,uid:2,age:20,city:北京,province:北京,country:中国,address:中国北京市海淀区,location:{lat:39.970718,lon:116.325747}} { index : { _index : twitter, _id: 2 }} {user:东城区-老刘, DOB:1981-01-01, message:出发下一站云南,uid:3,age:30,city:北京,province:北京,country:中国,address:中国北京市东城区台基厂三条3号,location:{lat:39.904313,lon:116.412754}} { index : { _index : twitter, _id: 3} } {user:东城区-李四, DOB:1982-01-01, message:happy birthday!,uid:4,age:30,city:北京,province:北京,country:中国,address:中国北京市东城区,location:{lat:39.893801,lon:116.408986}} { index : { _index : twitter, _id: 4} } {user:朝阳区-老贾,DOB:1983-01-01, message:123,gogogo,uid:5,age:35,city:北京,province:北京,country:中国,address:中国北京市朝阳区建国门,location:{lat:39.718256,lon:116.367910}} { index : { _index : twitter, _id: 5} } {user:朝阳区-老王,DOB:1984-01-01, message:Happy BirthDay My Friend!,uid:6,age:50,city:北京,province:北京,country:中国,address:中国北京市朝阳区国贸,location:{lat:39.918256,lon:116.467910}} { index : { _index : twitter, _id: 6} } {user:虹桥-老吴, DOB:1985-01-01, message:好友来了都今天我生日好友来了,什么 birthday happy 就成!,uid:7,age:90,city:上海,province:上海,country:中国,address:中国上海市闵行区,location:{lat:31.175927,lon:121.383328}} 这里共有6个文档。假设检索第一页的查询如下所示 GET twitter/_search { size: 2, query: { match: { city: 北京 } }, sort: [ { DOB: { order: asc } }, { user.keyword: { order: asc } } ] } 结果为 { took : 29, timed_out : false, _shards : { total : 1, successful : 1, skipped : 0, failed : 0 }, hits : { total : { value : 5, relation : eq }, max_score : null, hits : [ { _index : twitter, _type : _doc, _id : 1, _score : null, _source : { user : 双榆树-张三, DOB : 1980-01-01, message : 今儿天气不错啊出去转转去, uid : 2, age : 20, city : 北京, province : 北京, country : 中国, address : 中国北京市海淀区, location : { lat : 39.970718, lon : 116.325747 } }, sort : [ 315532800000, 双榆树-张三 ] }, { _index : twitter, _type : _doc, _id : 2, _score : null, _source : { user : 东城区-老刘, DOB : 1981-01-01, message : 出发下一站云南, uid : 3, age : 30, city : 北京, province : 北京, country : 中国, address : 中国北京市东城区台基厂三条3号, location : { lat : 39.904313, lon : 116.412754 } }, sort : [ 347155200000, 东城区-老刘 ] } ] } } 上述请求的结果包括每个文档的 sort 值数组。 这些 sort 值可以与 search_after 参数一起使用以开始返回在这个结果列表之后的任何文档。 例如我们可以使用上一个文档的 sort 值并将其传递给 search_after 以检索下一页结果 GET twitter/_search { size: 2, query: { match: { city: 北京 } }, search_after: [ 347155200000, 东城区-老刘 ], sort: [ { DOB: { order: asc } }, { user.keyword: { order: asc } } ] } 搜索结果为 { took : 47, timed_out : false, _shards : { total : 1, successful : 1, skipped : 0, failed : 0 }, hits : { total : { value : 5, relation : eq }, max_score : null, hits : [ { _index : twitter, _type : _doc, _id : 3, _score : null, _source : { user : 东城区-李四, DOB : 1982-01-01, message : happy birthday!, uid : 4, age : 30, city : 北京, province : 北京, country : 中国, address : 中国北京市东城区, location : { lat : 39.893801, lon : 116.408986 } }, sort : [ 378691200000, 东城区-李四 ] }, { _index : twitter, _type : _doc, _id : 4, _score : null, _source : { user : 朝阳区-老贾, DOB : 1983-01-01, message : 123,gogogo, uid : 5, age : 35, city : 北京, province : 北京, country : 中国, address : 中国北京市朝阳区建国门, location : { lat : 39.718256, lon : 116.367910 } }, sort : [ 410227200000, 朝阳区-老贾 ] } ] } }
注意当我们使用 search_after 时from 值必须设置为 0 或者 -1。
它与 scroll API 非常相似但与它不同search_after 参数是无状态的它始终针对最新版本的搜索器进行解析。 因此排序顺序可能会在步行期间发生变化具体取决于索引的更新和删除。
计数
我们经常会查询我们的索引里到底有多少文档那么我们可以使用_count重点来查询 GET twitter/_count
如果我们想知道满足条件的文档的数量我们可以采用如下的格式 GET twitter/_count { query: { match: { city: 北京 } } }
查询 在我们使用 match query 时默认的操作是 OR我们可以做如下的查询 GET twitter/_search { query: { match: { user: { query: 朝阳区-老贾, operator: or } } } } 这是因为默认的操作是 or 操作。上面查询的结果是任何文档匹配“朝”“阳”“区”“老”及“贾”这5个字中的任何一个将被显示 hits : [ { _index : twitter, _type : _doc, _id : 4, _score : 4.4209847, _source : { user : 朝阳区-老贾, message : 123,gogogo, uid : 5, age : 35, city : 北京, province : 北京, country : 中国, address : 中国北京市朝阳区建国门, location : { lat : 39.718256, lon : 116.367910 } } }, { _index : twitter, _type : _doc, _id : 5, _score : 2.9019678, _source : { user : 朝阳区-老王, message : Happy BirthDay My Friend!, uid : 6, age : 50, city : 北京, province : 北京, country : 中国, address : 中国北京市朝阳区国贸, location : { lat : 39.918256, lon : 116.467910 } } }, { _index : twitter, _type : _doc, _id : 2, _score : 0.8713734, _source : { user : 东城区-老刘, message : 出发下一站云南, uid : 3, age : 30, city : 北京, province : 北京, country : 中国, address : 中国北京市东城区台基厂三条3号, location : { lat : 39.904313, lon : 116.412754 } } }, { _index : twitter, _type : _doc, _id : 6, _score : 0.4753614, _source : { user : 虹桥-老吴, message : 好友来了都今天我生日好友来了,什么 birthday happy 就成!, uid : 7, age : 90, city : 上海, province : 上海, country : 中国, address : 中国上海市闵行区, location : { lat : 31.175927, lon : 121.383328 } } }, { _index : twitter, _type : _doc, _id : 3, _score : 0.4356867, _source : { user : 东城区-李四, message : happy birthday!, uid : 4, age : 30, city : 北京, province : 北京, country : 中国, address : 中国北京市东城区, location : { lat : 39.893801, lon : 116.408986 } } } ]
我们也可以设置参数 minimum_should_match 来设置至少匹配的 term。比如 GET twitter/_search { query: { match: { user: { query: 朝阳区-老贾, operator: or, minimum_should_match: 3 } } } }
上面显示我们至少要匹配“朝”“阳”“区”“老” 及 “贾” 这5个中的3个字才可以。显示结果 hits : [ { _index : twitter, _type : _doc, _id : 4, _score : 4.4209847, _source : { user : 朝阳区-老贾, message : 123,gogogo, uid : 5, age : 35, city : 北京, province : 北京, country : 中国, address : 中国北京市朝阳区建国门, location : { lat : 39.718256, lon : 116.367910 } } }, { _index : twitter, _type : _doc, _id : 5, _score : 2.9019678, _source : { user : 朝阳区-老王, message : Happy BirthDay My Friend!, uid : 6, age : 50, city : 北京, province : 北京, country : 中国, address : 中国北京市朝阳区国贸, location : { lat : 39.918256, lon : 116.467910 } } } ] 我们也可以改为 and 操作 GET twitter/_search { query: { match: { user: { query: 朝阳区-老贾, operator: and } } } }
显示的结果是 hits : [ { _index : twitter, _type : _doc, _id : 4, _score : 4.4209847, _source : { user : 朝阳区-老贾, message : 123,gogogo, uid : 5, age : 35, city : 北京, province : 北京, country : 中国, address : 中国北京市朝阳区建国门, location : { lat : 39.718256, lon : 116.367910 } } } ]