Elasticsearch update api

Update API可以根据提供的脚本更新文档。 该操作从索引获取文档,运行脚本(脚本语言和参数是可选的),并返回操作的结果(也允许删除或忽略该操作)。 使用版本控制来确保在“get”(查询文档)和“reindex”(重新索引文档)期间没有发生更新。

值得注意的是,该操作会重新索引文档(也就是说更新操作会先查文档,对文档合并,删除之前的文档,重新添加合并的文档。),它只是减少了网络往返以及减少了get(获取文档)和index(索引文档)之间版本冲突的可能性。 需要启用_source字段才能使此特性生效。

比如,索引一个简单的文档:

PUT test/_doc/1
{
    "counter" : 1,
    "tags" : ["red"]
}

Scripted updates

以下示例演示了如何执行一个增加counter的脚本:

POST test/_doc/1/_update
{
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    }
}

现在我们就可以往tags列表里添加一个tag(注意,如果tag存在,仍会添加,因为它是一个list)

POST test/_doc/1/_update
{
    "script" : {
        "source": "ctx._source.tags.add(params.tag)",
        "lang": "painless",
        "params" : {
            "tag" : "blue"
        }
    }
}

不止_source,以下变量也可以通过ctx来取得: _index, _type, _id, _version, _routing and _now(当前的时间戳)

以下示例演示了如何获取_id,比如:

POST test/_doc/1/_update
{
    "script" : "ctx._source.tags.add(ctx._id)"
}

也可以向文档添加新字段:

POST test/_doc/1/_update
{
    "script" : "ctx._source.new_field = 'value_of_new_field'"
}

从文档移除某个字段:

POST test/_doc/1/_update
{
    "script" : "ctx._source.remove('new_field')"
}

甚至可以改变已执行的操作。 以下示例:如果标签字段包含green,将删除doc,否则它不执行任何操作(即该操作会被忽略,返回noop):

POST test/_doc/1/_update
{
    "script" : {
        "source": "if (ctx._source.tags.contains(params.tag)) { ctx.op = 'delete' } else { ctx.op = 'none' }",
        "lang": "painless",
        "params" : {
            "tag" : "green"
        }
    }
}

更新部分文档

update API还支持传递部分文档,该部分文档将合并到现有文档中(简单的递归合并,对象的内部合并,替换核心”keys/values”和数组)。 要完全替换现有文档,应使用index API。 以下示例演示了如何使用部分更新向现有文档添加新字段:

POST test/_doc/1/_update
{
    "doc" : {
        "name" : "new_name"
    }
}

如果同时指定了doc和script,会报错。 最好是将部分文档的字段对放在脚本本身中(目前我还不知道该怎么操作)。

POST test/_doc/1/_update
{
  "doc" : {
        "age" : "18"
    },
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    }
}

返回结果如下:

{
  "error": {
    "root_cause": [
      {
        "type": "action_request_validation_exception",
        "reason": "Validation Failed: 1: can't provide both script and doc;"
      }
    ],
    "type": "action_request_validation_exception",
    "reason": "Validation Failed: 1: can't provide both script and doc;"
  },
  "status": 400
}

检测noop更新
如果指定了doc,则其值将与现有_source合并。 默认情况下,不更改任何内容的更新,会检测到并会返回“result”:“noop”,如下所示:

POST test/_doc/1/_update
{
    "doc" : {
        "name" : "new_name"
    }
}

如果在发送请求之前name是new_name,则忽略整个更新请求。 如果请求被忽略,响应中的result元素将返回noop。

{
  "_index": "test",
  "_type": "_doc",
  "_id": "1",
  "_version": 2,
  "result": "noop",
  "_shards": {
    "total": 0,
    "successful": 0,
    "failed": 0
  }
}

设置”detect_noop”: false可以禁用这种默认行为:

POST test/_doc/1/_update
{
    "doc" : {
        "name" : "new_name"
    },
    "detect_noop": false
}

Upserts

 如果文档尚不存在,则upsert元素的内容将作为新文档插入。 如果文档确实存在,则执行脚本:

POST test/_doc/1/_update
{
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    },
    "upsert" : {
        "counter" : 1
    }
}

scripted_upsert
如果希望无论文档是否存在,都运行脚本(即使用脚本处理初始化文档而不是upsert元素)可以将scripted_upsert设置为true:

POST sessions/session/dh3sgudg8gsrgl/_update
{
    "scripted_upsert":true,
    "script" : {
        "id": "my_web_session_summariser",
        "params" : {
            "pageViewEvent" : {
                "url":"foo.com/bar",
                "response":404,
                "time":"2014-01-01 12:32"
            }
        }
    },
    "upsert" : {}
}

下面来看看和直接写脚本不用upsert的区别,当文档不存在时,直接下面这样写会报错。

POST test/_doc/1/_update
{
    "scripted_upsert":true,
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    }
}

返回错误消息如下:

{
  "error": {
    "root_cause": [
      {
        "type": "document_missing_exception",
        "reason": "[_doc][1]: document missing",
        "index_uuid": "YgmlkeEERGm20yUBDJHKtQ",
        "shard": "3",
        "index": "test"
      }
    ],
    "type": "document_missing_exception",
    "reason": "[_doc][1]: document missing",
    "index_uuid": "YgmlkeEERGm20yUBDJHKtQ",
    "shard": "3",
    "index": "test"
  },
  "status": 404
}

设置scripted_upsert:true,当文档不存在时,执行下面的代码:

POST test/_doc/1/_update
{
    "scripted_upsert":true,
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    },
    "upsert" : {
        "counter" : 10
    }
}

返回的结果如下:

{
  "_index": "test",
  "_type": "_doc",
  "_id": "1",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 6,
  "_primary_term": 1
}

可见,执行成功了,下面来看看文档:

{
  "_index": "test",
  "_type": "_doc",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
    "counter": 14
  }
}

counter的值为14,可见是先执行了upsert的内容,然后执行了脚本。

doc_as_upsert
将doc_as_upsert设置为true将使用doc的内容作为upsert值,而不是发送部分doc加上upsert文档:

POST test/_doc/1/_update
{
    "doc" : {
        "name" : "new_name"
    },
    "doc_as_upsert" : true
}

下面来看看和直接写doc的区别:

POST test/_doc/1/_update
{
    "doc" : {
        "name" : "new_name"
    }
}

当文档不存在时,设置doc_as_upsert为true,可以成功执行。而上面这种情况会报错,提示文档不存在。如果向下面这样写会出现什么情况呢?

POST test/_doc/1/_update
{
    "doc" : {
        "name" : "new_name"
    },
    "upsert" : {
        "counter" : 10
    },
    "doc_as_upsert" : true
}

结果是upsert永远不会被执行,不管文档存在不存在,始终执行的是doc的内容。

转载: https://www.cnblogs.com/ginb/p/9413382.html

MySQL 主键和索引区别

主键:

所谓主键就是能够唯一标识表中某一行的属性或属性组,一个表只能有一个主键,是唯一性索引。书大家都看过吧,每页有个页码,我们的数据表主键就相当于是这个页码。

索引:

索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。索引相当于书的目录,有了目录我们可以很快的知道这本书的基本内容和结构,数据索引也一样,它可以加快数据表的查询速度。

主键是索引的一种,唯一性索引。

choco设置软件默认安装路径

Chocolatey,windows下的包管理器

因为 choco 的会将软件默认安装到 choco 自己的目录下,所以我们可以修改软件的安装目录,很简单

创建名为ChocolateyInstall的环境变量,值为想要安装的目录。

这样就可以了。

mysql 忘记root密码解决办法

当前版本:mysql5.7

找到my.cnf 一般在/etc/my.cnf 或 macos /usr/local/etc/my.cnf

在[mysqld] 下加入以下语句:skip-grant-tables

执行mysql -uroot -p ,如果提示输入密码,按回车。然后登入mysql

修改密码

use mysql;
update user set password=PASSWORD('你的密码') where user='root';
###  5.7执行以下语句
### update user set authentication_string=PASSWORD('你的密码')  where user='root';
flush priveleges;

再修改my.cnf 将刚添加的语句去掉。成功!!

PHP如何读取大文件

这里使用的yield 方法

function readTheFile($path) {
    $handle = fopen($path, 'r');

    while(!feof($handle)) {
        yield trim(fgets($handle));
    }

    fclose($handle);
}

$iterator = readTheFile('shakespeare.txt');
foreach ($iterator as $item) {
    echo $item;
}

Debian9 安装稳定版本的nginx

  1. 先安装依赖组件
sudo apt install curl gnupg2 ca-certificates lsb-release

2. 再仓库里生成list文件

echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

3. 增加key

curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -

4. 校验key

sudo apt-key fingerprint ABF5BD827BD9BF62
如果看到以下命令,表明成功
pub   rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
      573B FD6B 3D8F BC64 1079  A6AB ABF5 BD82 7BD9 BF62
uid   [ unknown] nginx signing key <signing-key@nginx.com>

5. 安装nginx

sudo apt update
sudo apt install nginx