Elasticsearch常用的相关操作汇总

本文将只发表在CSDN网站上,不会上传到百度文库,更不会发表在pudn网站上,如果发现此文被人上传到百度文库用于牟利,或者被pudn爬虫爬去,请联系作者或者帮忙举报,谢谢。

索引

更新索引的mapping

//新增或修改_mapping中的字段
POST my_index_demo/_mapping
{
  "properties":{
    "newVersion":{
      "type": "boolean"
    }
  }
}

向索引的字段中增加或修改newVersion字段。

通过查询更新文档

查询符合条件的文档,并新增字段newVersion,设置值为true,或者更新已有newVersion字段,设置为true。

POST my_index_demo/_update_by_query
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "labelField": {
              "value": "blabla"
            }
          }
        }
      ]
    }
  },
  "script":{
    "source":"ctx._source['newVersion']=true"
  }
}

根据查询条件,将符合条件的文档,通过script中的source字段进行修改,比如这儿就是给没有newVersion的文档新增newVersion字段,并设置为true,或者将文档中已有的newVersion字段值改为true。注意,如果通过script增加了字段,这个字段如果在_mapping中没有,就不能通过这个字段进行检索,解决办法就是通过通过更新mapping来让这个字段被索引。

根据查询条件,删除文档中的字段:

POST my_index_demo/_update_by_query
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "_id": {
              "value": "65006065497076723"
            }
          }
        }
      ]
    }
  },
  "script":{
    "source":"ctx._source.remove('newVersion')"
  }
}

上面的更新语句就是把_id字段满足条件的文档中的newVersion字段删除。

Painless脚本

创建脚本

POST _scripts/脚本名称 如:

POST _scripts/my_demo_script
{
  "script" : {
    "lang" : "painless",
    "source" : """
    boolean containsCityId = false;
    if(doc["newVersion"].size() > 0 && doc["newVersion"].value){
        List cityList =doc["cityIds"];
        for(id in cityList){
            if(params.cityIds.contains(id)){
                containsCityId=true;
            }
        }
    }
    return containsCityId;
    """
    }
}

创建了一个名称为my_demo_script的脚本,这样在后续查询的时候可以根据这个脚本名称引用脚本,而不用在DSL语句中内嵌大段的脚本,而且预先将脚本保存到ES中,可以预先编译,提高查询效率。

这段脚本的意思是如果文档中有newVersion这个字段,并且字段值为true的情况下,判断参数中的cityIds列表与ES文档中的cityIds是否有交集。

lang字段指出这个脚本是painless,因为ES支持多种脚本语言。

source内容是脚本,当脚本需要换行的时候用三个双引号"比较方便。

根据脚本查询

POST /my_index_demo/_search
{
	"from": 0,
	"size": 100,
	"timeout": "100ms",
	"query": {
		"bool": {
			"filter": [{
				"term": {
					"labeField": {
						"value": "blabla",
						"boost": 1.0
					}
				}
			},  {
				"script": {
					"script": {
						"id": "my_demo_script",
						"params": {
							"cityIds": ["5101","3201","3213"]
						}
					},
					"boost": 1.0
				}
			}],
			"adjust_pure_negative": true,
			"boost": 1.0
		}
	},
	"_source": {
		"includes": ["newVersion", "cityIds","labelField"],
		"excludes": []
	},
	"sort": [{
		"updateTime": {
			"order": "asc"
		}
	}]
}

通过脚本名字和脚本需要的参数params进行查询。

脚本中判断某个字段是否存在

painless脚本从doc中获取字段的结果都是List类型,如果要判断文档中是否有某个字段可以用

doc[“字段名”].size() > 0 判断

如果判断文档中某个boolean类型字段值是否为true可以用

doc[“字段名”].value

刚才不是说,doc[“字段名”]返回的是List么,怎么能对List类型用.value取值呢?其实通过Elaticsearch的源码org.elasticsearch.index.fielddata.ScriptDocValues.Booleans#getValue可以看到获取value的时候,自动帮你获取List中的第一个元素了:

   public static final class Booleans extends ScriptDocValues<Boolean> {

        private final SortedNumericDocValues in;
        private boolean[] values = new boolean[0];
        private int count;

        public Booleans(SortedNumericDocValues in) {
            this.in = in;
        }

        @Override
        public void setNextDocId(int docId) throws IOException {
            if (in.advanceExact(docId)) {
                resize(in.docValueCount());
                for (int i = 0; i < count; i++) {
                    values[i] = in.nextValue() == 1;
                }
            } else {
                resize(0);
            }
        }

        /**
         * Set the {@link #size()} and ensure that the {@link #values} array can
         * store at least that many entries.
         */
        protected void resize(int newSize) {
            count = newSize;
            values = grow(values, count);
        }

        public boolean getValue() {
          	// 自动帮我们获取List中的第一个元素了
            return get(0);
        }

        @Override
        public Boolean get(int index) {
            if (count == 0) {
                throw new IllegalStateException(
                    "A document doesn't have a value for a field! "
                        + "Use doc[<field>].size()==0 to check if a document is missing a field!"
                );
            }
            return values[index];
        }

        @Override
        public int size() {
            return count;
        }

        private static boolean[] grow(boolean[] array, int minSize) {
            assert minSize >= 0 : "size must be positive (got " + minSize + "): likely integer overflow?";
            if (array.length < minSize) {
                return Arrays.copyOf(array, ArrayUtil.oversize(minSize, 1));
            } else return array;
        }
    }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:创作都市 设计师:CSDN官方博客 返回首页
评论

打赏作者

pilaf1990

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值